【Android】21.4 图片动画缩放示例

分类:C#、Android、VS2015;

创建日期:2016-03-21

一、简介

该例子演示如何动画缩放图片,实现类似“点击看大图”的效果。

二、示例

1、运行截图

  

2、设计步骤

(1)添加图片

在Resources/no-dpi文件夹下添加4张图片(2个缩略图,2个大图)。

(2)添加ch2104MyImageButton.cs

using Android.Content;
using Android.Widget;
using System.Drawing;
using Android.Graphics.Drawables;
using Android.Util;
using Android.Content.Res;
using Android.Graphics;
using Color = Android.Graphics.Color;

namespace MyDemos.SrcDemos
{
    /// <summary>
    /// 演示drawable-nodpi文件夹下的图片资源缩放(点击看大图)
    /// </summary>
    public class ch2104MyImageButton : ImageButton
    {
        private Rectangle cachedBounds;
        private Drawable foregroundDrawable;

        public ch2104MyImageButton(Context context)
            : this(context, null)
        {
        }

        public ch2104MyImageButton(Context context, IAttributeSet attrs)
            : this(context, attrs, 0)
        {
        }

        public ch2104MyImageButton(Context context, IAttributeSet attrs, int defStyle)
            : base(context, attrs, defStyle)
        {
            Init();
        }

        protected override void DrawableStateChanged()
        {
            base.DrawableStateChanged();
            if (foregroundDrawable.IsStateful)
            {
                foregroundDrawable.SetState(GetDrawableState());
            }
            Invalidate();
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);
            base.OnDraw(canvas);
            foregroundDrawable.SetBounds(cachedBounds.Left, cachedBounds.Top, cachedBounds.Right, cachedBounds.Bottom);
            foregroundDrawable.Draw(canvas);
        }

        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);
            cachedBounds = new Rectangle(0, 0, w, h);
        }

        private void Init()
        {
            SetBackgroundColor(Color.White);
            SetPadding(0, 0, 0, 0);

            TypedArray a = Context.ObtainStyledAttributes(new[] { Android.Resource.Attribute.SelectableItemBackground });
            foregroundDrawable = a.GetDrawable(0);
            foregroundDrawable.SetCallback(this);
            a.Recycle();
        }
    }
}

(3)添加ch2104Zoom.axml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">
        <TextView
            style="?android:textAppearanceSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="提示:单击缩略图【放大/缩小】该图片。" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:orientation="horizontal">
            <MyDemos.SrcDemos.ch2104MyImageButton
                android:id="@+id/thumb_button_1"
                android:layout_width="100dp"
                android:layout_height="75dp"
                android:layout_marginRight="1dp"
                android:src="@drawable/ch2103thumb1"
                android:scaleType="centerCrop"
                android:contentDescription="缩略图1" />
            <MyDemos.SrcDemos.ch2104MyImageButton
                android:id="@+id/thumb_button_2"
                android:layout_width="100dp"
                android:layout_height="75dp"
                android:src="@drawable/ch2103thumb2"
                android:scaleType="centerCrop"
                android:contentDescription="缩略图2" />
        </LinearLayout>
    </LinearLayout>
    <ImageView
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"
        android:contentDescription="这是放大后的图片(点击消失)" />
</FrameLayout>

(4)添加ch2104ZoomActivity.cs

using System;
using System.Collections.Generic;
using Android.App;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Animation;
using Android.Graphics;
using Android.Views.Animations;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "【例21-4】图片动画缩放示例")]
    public class ch2104ZoomActivity : Activity
    {
        private Animator currentAnimator;
        private int shortAnimationDuration;
        private Dictionary<int, AnimatorSet> expandingAnimators;
        private Dictionary<int, AnimatorSet> shrinkingAnimators;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.ch2104Zoom);

            shortAnimationDuration = Resources.GetInteger(Android.Resource.Integer.ConfigShortAnimTime);
            expandingAnimators = new Dictionary<int, AnimatorSet>(2);
            shrinkingAnimators = new Dictionary<int, AnimatorSet>(2);

            View thumb1View = FindViewById(Resource.Id.thumb_button_1);
            thumb1View.Tag = Resource.Drawable.ch2103image1;
            thumb1View.Click += ZoomImageFromThumb;

            View thumb2View = FindViewById(Resource.Id.thumb_button_2);
            thumb2View.Tag = Resource.Drawable.ch2103image2;
            thumb2View.Click += ZoomImageFromThumb;

        }

        /// <summary>
        ///  控制ImageView的放大速率
        /// </summary>
        /// <param name="startBounds">缩略图的矩形区域</param>
        /// <param name="finalBounds">大图的可见区域</param>
        /// <returns></returns>
        private static float CalculateStartScale(Rect startBounds, Rect finalBounds)
        {
            float startScale;
            float finalBoundsRatio = finalBounds.Width() / (float)finalBounds.Height();
            float startBoundsRatio = startBounds.Width() / (float)startBounds.Height();

            if (finalBoundsRatio > startBoundsRatio)
            {
                // 横向展开
                startScale = (float)startBounds.Height() / finalBounds.Height();
                float startWidth = startScale * finalBounds.Width();
                float deltaWidth = (startWidth - startBounds.Width()) / 2;
                startBounds.Left -= (int)deltaWidth;
                startBounds.Right += (int)deltaWidth;
            }
            else
            {
                // 纵向展开
                startScale = (float)startBounds.Width() / finalBounds.Width();
                float startHeight = startScale * finalBounds.Height();
                float deltaHeight = (startHeight - startBounds.Height()) / 2;
                startBounds.Top -= (int)deltaHeight;
                startBounds.Bottom += (int)deltaHeight;
            }
            return startScale;
        }

        /// <summary>
        /// 创建展开的动画集合 - 让缩略图看起来逐渐变大
        /// </summary>
        /// <param name="expandedView">缩略图放大用的ImageView</param>
        /// <param name="startBounds">缩略图的可见区域(全局坐标)</param>
        /// <param name="finalBounds">放大后的矩形区域(全局坐标)</param>
        /// <param name="startScale"></param>
        /// <returns></returns>
        private AnimatorSet BuildExpandingAnimatorSet(ImageView expandedView, Rect startBounds, Rect finalBounds, float startScale)
        {
            // 按顺序缓存每次展开的动画集合,这些实例都是从初始位置开始
            int key = startBounds.GetHashCode();
            if (expandingAnimators.ContainsKey(key))
            {
                return expandingAnimators[key];
            }

            AnimatorSet expandSet = new AnimatorSet();
            expandSet.Play(ObjectAnimator.OfFloat(expandedView, View.X, startBounds.Left, finalBounds.Left))
                     .With(ObjectAnimator.OfFloat(expandedView, View.Y, startBounds.Top, finalBounds.Top))
                     .With(ObjectAnimator.OfFloat(expandedView, "ScaleX", startScale, 1f))
                     .With(ObjectAnimator.OfFloat(expandedView, "ScaleY", startScale, 1f));
            expandSet.SetDuration(shortAnimationDuration);
            expandSet.SetInterpolator(new DecelerateInterpolator());
            expandSet.AnimationEnd += NullOutCurrentAnimator;
            expandSet.AnimationCancel += NullOutCurrentAnimator;

            expandingAnimators.Add(key, expandSet);
            return expandSet;
        }

        private void NullOutCurrentAnimator(object sender, EventArgs eventArgs)
        {
            if (currentAnimator == null)
            {
                return;
            }
            currentAnimator = null;
        }

        /// <summary>
        /// 创建从大图逐步缩小到缩略图的动画集合
        /// </summary>
        /// <param name="bigView">大图的视图</param>
        /// <param name="thumbView">缩略图的视图</param>
        /// <param name="startBounds">缩略图变为可见的区域</param>
        /// <param name="scale">缩放速率</param>
        /// <returns></returns>
        private AnimatorSet BuildShrinkingAnimatorSet(View bigView, View thumbView, Rect startBounds, float scale)
        {
            if (shrinkingAnimators.ContainsKey(thumbView.Id))
            {
                return shrinkingAnimators[thumbView.Id];
            }

            AnimatorSet shrinkSet = new AnimatorSet();
            shrinkSet.Play(ObjectAnimator.OfFloat(bigView, View.X, startBounds.Left))
                     .With(ObjectAnimator.OfFloat(bigView, View.Y, startBounds.Top))
                     .With(ObjectAnimator.OfFloat(bigView, "ScaleX", scale))
                     .With(ObjectAnimator.OfFloat(bigView, "ScaleY", scale));
            shrinkSet.SetDuration(shortAnimationDuration);
            shrinkSet.SetInterpolator(new DecelerateInterpolator());
            shrinkSet.AnimationEnd += (sender1, args1) =>
            {
                thumbView.Alpha = 1.0f;
                bigView.Visibility = ViewStates.Gone;
                NullOutCurrentAnimator(sender1, args1);
            };

            shrinkSet.AnimationCancel += (sender1, args1) =>
            {
                thumbView.Alpha = 1.0f;
                bigView.Visibility = ViewStates.Gone;
                NullOutCurrentAnimator(sender1, args1);
            };

            shrinkingAnimators.Add(thumbView.Id, shrinkSet);
            return shrinkSet;
        }

        /// <summary>
        /// 获取控制展开图片的ImageView的引用
        /// </summary>
        /// <param name="thumbView"></param>
        /// <returns></returns>
        private ImageView GetExpandedImageView(View thumbView)
        {
            ImageView expandedImageView = FindViewById<ImageView>(Resource.Id.expanded_image);
            int finalImageResourceId = (int)thumbView.Tag; // In this example we store the resource id of the big image in the tag of the thumbnail.
            expandedImageView.SetImageResource(finalImageResourceId);
            thumbView.Alpha = 0.2f; //0f;
            expandedImageView.Visibility = ViewStates.Visible;
            expandedImageView.PivotX = 0f;
            expandedImageView.PivotY = 0f;
            return expandedImageView;
        }

        private void ZoomImageFromThumb(object sender, EventArgs eventArgs)
        {
            View thumbView = (View)sender;
            ImageView expandedImageView = GetExpandedImageView(thumbView);

            if (currentAnimator != null)
            {
                currentAnimator.Cancel();
            }
            Rect startBounds = new Rect();
            Rect finalBounds = new Rect();
            Point globalOffset = new Point();

            thumbView.GetGlobalVisibleRect(startBounds);

            FindViewById(Resource.Id.container).GetGlobalVisibleRect(finalBounds, globalOffset);
            startBounds.Offset(-globalOffset.X, -globalOffset.Y);
            finalBounds.Offset(-globalOffset.X, -globalOffset.Y);

            float startScale = CalculateStartScale(startBounds, finalBounds);

            AnimatorSet expandSet = BuildExpandingAnimatorSet(expandedImageView, startBounds, finalBounds, startScale);
            expandSet.Start();
            currentAnimator = expandSet;

            expandedImageView.Click += (o, args) =>
            {
                if (currentAnimator != null)
                {
                    currentAnimator.Cancel();
                }

                AnimatorSet shrinkSet = BuildShrinkingAnimatorSet(expandedImageView, thumbView, startBounds, startScale);
                shrinkSet.Start();
                currentAnimator = shrinkSet;
            };
        }
    }
}
时间: 2024-11-08 19:14:45

【Android】21.4 图片动画缩放示例的相关文章

Android实现对图片的缩放、剪切、旋转、存储

Android实现对图片的缩放.剪切.旋转.存储 一.问题描述 在开发中,当我们需要的有一张大图片同时还需要一些小图片时,我们只需要通过代码对此图片进行不同比例的缩放即可,这样大大节约资源,减小了安装包的尺寸 .除缩放外,我们还经常对图片进行其他操作如裁剪.旋转.存储等. 这样我们可以编写对于图片进行处理的通用组件,方便开发.下面就分享一下对图片进行处理的组件BitmapUtil,案例界面: 二.技术点描述 1.通过BitmapFactory取得Bitmap Bitmap bm=BitmapFa

解决android:background背景图片被拉伸问题

ImageView中XML属性src和background的区别: background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸.src是图片内容(前景),bg是背景,可以同时使用. 此外:scaleType只对src起作用:bg可设置透明度,比如在ImageButton中就可以用android:scaleType控制图片的缩放方式 如上所述,background设置的图片会跟View组件给定的长宽比例进行拉伸.举个例子, 36x36 px的图标

android:background背景图片被拉伸问题

ImageView中XML属性src和background的区别: background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸.src是图片内容(前景),bg是背景,可以同时使用. 此外:scaleType只对src起作用:bg可设置透明度,比如在ImageButton中就可以用android:scaleType控制图片的缩放方式 如上所述,background设置的图片会跟View组件给定的长宽比例进行拉伸.举个例子, 36x36 px的图标

Android图片旋转,缩放,位移,倾斜,对称完整示例(二)——Bitmap.createBitmap()和Matrix

MainActivity如下: package cc.c; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.widget.ImageView; /** * Demo描述: * 利用B

Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix

MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.app.Activity; import android.graphics.Matrix; /** * Demo描述:

Android 中实现图片平移、缩放、旋转同步进行

前言 之前因为项目需求,其中使用到了图片的单击显示取消,图片平移缩放功能,昨天突然想再加上图片的旋转功能,在网上看了很多相关的例子,可是没看到能同时实现我想要的功能的. 需求:(1)图片平移.缩放.旋转等一系列操作后,图片需要自动居中显示.(2)图片旋转后选自动水平显示或者垂直显示(3)图片在放大缩小的同时都能旋转 Demo实现部分效果截图 Demo主要代码 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2

Android仿微信朋友圈图片浏览器(支持图片手势缩放,拖动)

※效果 ※使用到的开源库 PhotoView 图片缩放:支持双击缩放,手指捏拉缩放 https://github.com/chrisbanes/PhotoView Universalimageloader 图片下载缓存库 https://github.com/nostra13/Android-Universal-Image-Loader ViewPagerIndicator 分页指示器 https://github.com/JakeWharton/Android-ViewPagerIndicat

Android实现图片的缩放和拖动

概述:通过自定义ImageView控件,在xml布局里面调用自定的组件实现图片的缩放. /** * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 * * @author qiuwanyong */ public class MyImageView extends ImageView { /** * 初始化状态常量 */ public static final int STATUS_INIT = 1; /** * 图片放大状态常量 */ public static final i

Android小应用----图片的拖动、缩放

public class MainActivity extends Activity { private ImageView operImage; private PointF point = new PointF();//记录手指的位置 private PointF midPoint = new PointF();//记录手指间的中点的位置 private Matrix matrix = new Matrix();//记录拖动和缩放前手指按下的matrix private Matrix new