Android點擊縮略圖查看大圖的縮放動畫

原文地址 http://blog.csdn.net/qq_25806863/article/details/70156794

來自官方培訓課程https://developer.android.com/training/animation/zoom.html#animate

其實點擊小圖顯示大圖非常簡單的一種實現方式就是,在佈局中加一個全屏的ImageView,然後隱藏。點擊小圖就把圖片設置給大圖,然後大圖顯示。

這個文章裏也是這麼做的,不過這邊課程的重心在於講從縮略圖到大圖的動畫過程。動畫的目的是讓過程看起來像是從小的縮略圖的邊界開始放大到最終的大圖的。
這裏寫圖片描述

佈局

在佈局文件裏設置兩張小的ImageView,和一個全屏的ImageView。還要注意根佈局。

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    tools:context="com.sunlinlin.zoomingview.MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="159dp"
            android:layout_height="116dp"
            app:srcCompat="@drawable/xiaomao" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="159dp"
            android:layout_height="116dp"
            app:srcCompat="@mipmap/ic_launcher"/>

    </LinearLayout>

    <ImageView
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        android:scaleType="centerCrop"
        android:visibility="invisible" />
</RelativeLayout>

Activity

然後在Activit中進行一些簡單的設置,兩張小圖的點擊事件是通過動畫顯示大圖。

public class MainActivity extends AppCompatActivity {

    // 持有這個動畫的引用,讓他可以在動畫執行中途取消
    private Animator mCurrentAnimator;

    private int mShortAnimationDuration;

    private View imageView1;
    private View imageView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

        imageView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                zoomImageFromThumb(imageView1,R.drawable.xiaomao);
            }
        });
        imageView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                zoomImageFromThumb(imageView2,R.mipmap.ic_launcher);
            }
        });

        // 系統默認的短動畫執行時間 200
        mShortAnimationDuration = getResources().getInteger(
                android.R.integer.config_shortAnimTime);
    }

    private void initView() {
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        imageView2 = (ImageView) findViewById(R.id.imageView2);
    }
}

縮放動畫

都在註釋裏.

private void zoomImageFromThumb(final View thumbView, int imageResId) {
        // 如果有動畫正在運行,取消這個動畫
        if (mCurrentAnimator != null) {
            mCurrentAnimator.cancel();
        }

        // 加載顯示大圖的ImageView
        final ImageView expandedImageView = (ImageView) findViewById(
                R.id.expanded_image);
        expandedImageView.setImageResource(imageResId);

        // 計算初始小圖的邊界位置和最終大圖的邊界位置。
        final Rect startBounds = new Rect();
        final Rect finalBounds = new Rect();
        final Point globalOffset = new Point();

        // 小圖的邊界就是小ImageView的邊界,大圖的邊界因爲是鋪滿全屏的,所以就是整個佈局的邊界。
        // 然後根據偏移量得到正確的座標。
        thumbView.getGlobalVisibleRect(startBounds);
        findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset);
        startBounds.offset(-globalOffset.x, -globalOffset.y);
        finalBounds.offset(-globalOffset.x, -globalOffset.y);

        // 計算初始的縮放比例。最終的縮放比例爲1。並調整縮放方向,使看着協調。
        float startScale=0;
        if ((float) finalBounds.width() / finalBounds.height()
                > (float) startBounds.width() / startBounds.height()) {
            // 橫向縮放
            float startWidth = startScale * finalBounds.width();
            float deltaWidth = (startWidth - startBounds.width()) / 2;
            startBounds.left -= deltaWidth;
            startBounds.right += deltaWidth;
        } else {
            // 豎向縮放
            float startHeight = startScale * finalBounds.height();
            float deltaHeight = (startHeight - startBounds.height()) / 2;
            startBounds.top -= deltaHeight;
            startBounds.bottom += deltaHeight;
        }

        // 隱藏小圖,並顯示大圖
        thumbView.setAlpha(0f);
        expandedImageView.setVisibility(View.VISIBLE);

        // 將大圖的縮放中心點移到左上角。默認是從中心縮放
        expandedImageView.setPivotX(0f);
        expandedImageView.setPivotY(0f);

        //對大圖進行縮放動畫
        AnimatorSet set = new AnimatorSet();
        set.play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left, finalBounds.left))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top, finalBounds.top))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1f));
        set.setDuration(mShortAnimationDuration);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mCurrentAnimator = null;
            }
        });
        set.start();
        mCurrentAnimator = set;

        // 點擊大圖時,反向縮放大圖,然後隱藏大圖,顯示小圖。
        final float startScaleFinal = startScale;
        expandedImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mCurrentAnimator != null) {
                    mCurrentAnimator.cancel();
                }

                AnimatorSet set = new AnimatorSet();
                set.play(ObjectAnimator
                        .ofFloat(expandedImageView, View.X, startBounds.left))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.Y,startBounds.top))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.SCALE_X, startScaleFinal))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.SCALE_Y, startScaleFinal));
                set.setDuration(mShortAnimationDuration);
                set.setInterpolator(new DecelerateInterpolator());
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }
                });
                set.start();
                mCurrentAnimator = set;
            }
        });
    }

發佈了74 篇原創文章 · 獲贊 199 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章