zoom動畫,實現圖片點擊預覽效果


參考:https://developer.android.google.cn/training/animation/zoom.html

 1.創建Views

下面的布局包括了你想要zoom的大版本和小版本的view。

1.ImageButton是小版本的,能點擊的,點擊后顯示大版本的ImageView。

2.ImageView是大版本的,可以顯示ImageButton點擊后的樣式。

3.ImageView一開始是不可見的(invisible),當ImageButton點擊后,它會實現zoom動畫,就像從ImageButton上擴大顯示出來。

 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:id="@+id/container"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <LinearLayout android:layout_width="match_parent"
 7         android:layout_height="wrap_content"
 8         android:orientation="vertical"
 9         android:padding="16dp">
10 
11         <ImageButton
12             android:id="@+id/thumb_button_1"
13             android:layout_width="100dp"
14             android:layout_height="75dp"
15             android:layout_marginRight="1dp"
16             android:src="@drawable/thumb1"
17             android:scaleType="centerCrop"
18             android:contentDescription="@string/description_image_1" />
19 
20     </LinearLayout>
21 
22     <!-- 這個不可見的ImageView持有上面的ImageButton zoom后的圖片版本。
23     動畫沒有發生之前,它占據了整個屏幕。動畫開始,這個View從上面
24     ImageButton的范圍變化到他自己最終的范圍。
25          -->
26 
27     <ImageView
28         android:id="@+id/expanded_image"
29         android:layout_width="match_parent"
30         android:layout_height="match_parent"
31         android:visibility="invisible"
32         android:contentDescription="@string/description_zoom_touch_close" />
33 
34 </FrameLayout>

 

 2.設置zoom動畫

  在ImageButton上設置點擊事件,執行zoom動畫

 1 public class ZoomActivity extends FragmentActivity {
 2     // 保存下當前動畫類,以便可以隨時結束動畫
 3     private Animator mCurrentAnimator;
 4 
 5     //系統的短時長動畫持續時間(單位ms)
 6     // 對於不易察覺的動畫或者頻繁發生的動畫
 7     // 這個動畫持續時間是最理想的
 8     private int mShortAnimationDuration;
 9 
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.activity_zoom);
14 
15         // 給ImageButton設置點擊事件
16         final View thumb1View = findViewById(R.id.thumb_button_1);
17         thumb1View.setOnClickListener(new View.OnClickListener() {
18             @Override
19             public void onClick(View view) {
20         //執行zoom動畫方法
21                 zoomImageFromThumb(thumb1View, R.drawable.image1);
22             }
23         });
24 
25         //取回系統默認的短時長動畫持續時間
26         mShortAnimationDuration = getResources().getInteger(
27                 android.R.integer.config_shortAnimTime);
28     }
29     ...
30 }

 3.實現zoom動畫

  你需要把從正常大小的view到擴大以后的view這個過程作成動畫。

1.指定想要zoom的圖片給ImageView。(理想情況下,這個bitmap的大小不應該比屏幕大)

2.計算這個ImageView的開始和結束位置

3.把四個點和縮放大小的屬性同時作成動畫,從開始的狀態到結束的狀態。這四個動畫被添加到AnimatorSet中,方便他們同時執行。

4.當用戶再次點擊屏幕時,動畫要執行回去。一樣道理,給ImageView一個View.OnClickListener,然后隱藏ImageView。

  1 private void zoomImageFromThumb(final View thumbView, int imageResId) {
  2     // 如果有動畫在執行,立即取消,然后執行現在這個動畫
  3     if (mCurrentAnimator != null) {
  4         mCurrentAnimator.cancel();
  5     }
  6 
  7     // 加載高分辨率的圖片
  8     final ImageView expandedImageView = (ImageView) findViewById(
  9             R.id.expanded_image);
 10     expandedImageView.setImageResource(imageResId);
 11 
 12     // 計算開始和結束位置的圖片范圍
 13     final Rect startBounds = new Rect();
 14     final Rect finalBounds = new Rect();
 15     final Point globalOffset = new Point();
 16 
 17     // 開始的范圍就是ImageButton的范圍,
 18     // 結束的范圍是容器(FrameLayout)的范圍
 19     // getGlobalVisibleRect(Rect)得到的是view相對於整個硬件屏幕的Rect
 20     // 即絕對坐標,減去偏移,獲得動畫需要的坐標,即相對坐標
 21     // getGlobalVisibleRect(Rect,Point)中,Point獲得的是view在它在
 22     // 父控件上的坐標與在屏幕上坐標的偏移
 23     thumbView.getGlobalVisibleRect(startBounds);
 24     findViewById(R.id.container)
 25             .getGlobalVisibleRect(finalBounds, globalOffset);
 26     startBounds.offset(-globalOffset.x, -globalOffset.y);
 27     finalBounds.offset(-globalOffset.x, -globalOffset.y);
 28 
 29     // Adjust the start bounds to be the same aspect ratio as the final
 30     // bounds using the "center crop" technique. This prevents undesirable
 31     // stretching during the animation. Also calculate the start scaling
 32     // factor (the end scaling factor is always 1.0).
 33 
 34     // 下面這段邏輯其實就是保持縱橫比
 35     float startScale;
 36     // 如果結束圖片的寬高比比開始圖片的寬高比大
 37     // 就是結束時“視覺上”拉寬了(壓扁了)圖片
 38     if ((float) finalBounds.width() / finalBounds.height()
 39             > (float) startBounds.width() / startBounds.height()) {
 40         // Extend start bounds horizontally
 41         startScale = (float) startBounds.height() / finalBounds.height();
 42         float startWidth = startScale * finalBounds.width();
 43         float deltaWidth = (startWidth - startBounds.width()) / 2;
 44         startBounds.left -= deltaWidth;
 45         startBounds.right += deltaWidth;
 46     } else {
 47         // Extend start bounds vertically
 48         startScale = (float) startBounds.width() / finalBounds.width();
 49         float startHeight = startScale * finalBounds.height();
 50         float deltaHeight = (startHeight - startBounds.height()) / 2;
 51         startBounds.top -= deltaHeight;
 52         startBounds.bottom += deltaHeight;
 53     }
 54 
 55     // Hide the thumbnail and show the zoomed-in view. When the animation
 56     // begins, it will position the zoomed-in view in the place of the
 57     // thumbnail.
 58 
 59     // 隱藏小的圖片,展示大的圖片。當動畫開始的時候,
 60     // 要把大的圖片發在小的圖片的位置上
 61 
 62     //小的設置透明
 63     thumbView.setAlpha(0f);
 64     //大的可見
 65     expandedImageView.setVisibility(View.VISIBLE);
 66 
 67     // Set the pivot point for SCALE_X and SCALE_Y transformations
 68     // to the top-left corner of the zoomed-in view (the default
 69     // is the center of the view).
 70     expandedImageView.setPivotX(0f);
 71     expandedImageView.setPivotY(0f);
 72 
 73     // Construct and run the parallel animation of the four translation and
 74     // scale properties (X, Y, SCALE_X, and SCALE_Y).
 75     AnimatorSet set = new AnimatorSet();
 76     set
 77             .play(ObjectAnimator.ofFloat(expandedImageView, View.X,
 78                     startBounds.left, finalBounds.left))
 79             .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
 80                     startBounds.top, finalBounds.top))
 81             .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
 82             startScale, 1f)).with(ObjectAnimator.ofFloat(expandedImageView,
 83                     View.SCALE_Y, startScale, 1f));
 84     set.setDuration(mShortAnimationDuration);
 85     set.setInterpolator(new DecelerateInterpolator());
 86     set.addListener(new AnimatorListenerAdapter() {
 87         @Override
 88         public void onAnimationEnd(Animator animation) {
 89             mCurrentAnimator = null;
 90         }
 91 
 92         @Override
 93         public void onAnimationCancel(Animator animation) {
 94             mCurrentAnimator = null;
 95         }
 96     });
 97     set.start();
 98     mCurrentAnimator = set;
 99 
100     // Upon clicking the zoomed-in image, it should zoom back down
101     // to the original bounds and show the thumbnail instead of
102     // the expanded image.
103 
104     // 再次點擊返回小的圖片,就是上面擴大的反向動畫。即預覽完成
105     final float startScaleFinal = startScale;
106     expandedImageView.setOnClickListener(new View.OnClickListener() {
107         @Override
108         public void onClick(View view) {
109             if (mCurrentAnimator != null) {
110                 mCurrentAnimator.cancel();
111             }
112 
113             // Animate the four positioning/sizing properties in parallel,
114             // back to their original values.
115             AnimatorSet set = new AnimatorSet();
116             set.play(ObjectAnimator
117                         .ofFloat(expandedImageView, View.X, startBounds.left))
118                         .with(ObjectAnimator
119                                 .ofFloat(expandedImageView,
120                                         View.Y,startBounds.top))
121                         .with(ObjectAnimator
122                                 .ofFloat(expandedImageView,
123                                         View.SCALE_X, startScaleFinal))
124                         .with(ObjectAnimator
125                                 .ofFloat(expandedImageView,
126                                         View.SCALE_Y, startScaleFinal));
127             set.setDuration(mShortAnimationDuration);
128             set.setInterpolator(new DecelerateInterpolator());
129             set.addListener(new AnimatorListenerAdapter() {
130                 @Override
131                 public void onAnimationEnd(Animator animation) {
132                     thumbView.setAlpha(1f);
133                     expandedImageView.setVisibility(View.GONE);
134                     mCurrentAnimator = null;
135                 }
136 
137                 @Override
138                 public void onAnimationCancel(Animator animation) {
139                     thumbView.setAlpha(1f);
140                     expandedImageView.setVisibility(View.GONE);
141                     mCurrentAnimator = null;
142                 }
143             });
144             set.start();
145             mCurrentAnimator = set;
146         }
147     });
148 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM