zoukankan      html  css  js  c++  java
  • 【Android】21.4 图片动画缩放示例

    分类:C#、Android、VS2015;

    创建日期:2016-03-21

    一、简介

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

    二、示例

    1、运行截图

    image   image

    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;
                };
            }
        }
    }
  • 相关阅读:
    坐看夕阳
    张学孟 (帮别人名字作诗)
    光棍节有感
    我懂
    陶婷(帮别人名字作诗)
    你的爱是不是在等着我
    OpenCV数据读写操作
    数字图像处理中的形态学
    C++/C学习笔记(一)
    利用opencv绘制 灰度直方图 RGB直方图 HSV直方图 直方图均衡化
  • 原文地址:https://www.cnblogs.com/rainmj/p/5300471.html
Copyright © 2011-2022 走看看