Android實現(xiàn)圖片點擊預(yù)覽效果(zoom動畫)
參考:https://developer.android.google.cn/training/animation/zoom.html
1.創(chuàng)建Views
下面的布局包括了你想要zoom的大版本和小版本的view。
1.ImageButton是小版本的,能點擊的,點擊后顯示大版本的ImageView。
2.ImageView是大版本的,可以顯示ImageButton點擊后的樣式。
3.ImageView一開始是不可見的(invisible),當(dāng)ImageButton點擊后,它會實現(xiàn)zoom動畫,就像從ImageButton上擴(kuò)大顯示出來。
<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"> <ImageButton android:id="@+id/thumb_button_1" android:layout_width="100dp" android:layout_height="75dp" android:layout_marginRight="1dp" android:src="@drawable/thumb1" android:scaleType="centerCrop" android:contentDescription="@string/description_image_1" /> </LinearLayout> <!-- 這個不可見的ImageView持有上面的ImageButton zoom后的圖片版本。 動畫沒有發(fā)生之前,它占據(jù)了整個屏幕。動畫開始,這個View從上面 ImageButton的范圍變化到他自己最終的范圍。 --> <ImageView android:id="@+id/expanded_image" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="invisible" android:contentDescription="@string/description_zoom_touch_close" /> </FrameLayout>
2.設(shè)置zoom動畫
在ImageButton上設(shè)置點擊事件,執(zhí)行zoom動畫
public class ZoomActivity extends FragmentActivity { // 保存下當(dāng)前動畫類,以便可以隨時結(jié)束動畫 private Animator mCurrentAnimator; //系統(tǒng)的短時長動畫持續(xù)時間(單位ms) // 對于不易察覺的動畫或者頻繁發(fā)生的動畫 // 這個動畫持續(xù)時間是最理想的 private int mShortAnimationDuration; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_zoom); // 給ImageButton設(shè)置點擊事件 final View thumb1View = findViewById(R.id.thumb_button_1); thumb1View.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //執(zhí)行zoom動畫方法 zoomImageFromThumb(thumb1View, R.drawable.image1); } }); //取回系統(tǒng)默認(rèn)的短時長動畫持續(xù)時間 mShortAnimationDuration = getResources().getInteger( android.R.integer.config_shortAnimTime); } ... }
3.實現(xiàn)zoom動畫
你需要把從正常大小的view到擴(kuò)大以后的view這個過程作成動畫。
1.指定想要zoom的圖片給ImageView。(理想情況下,這個bitmap的大小不應(yīng)該比屏幕大)
2.計算這個ImageView的開始和結(jié)束位置
3.把四個點和縮放大小的屬性同時作成動畫,從開始的狀態(tài)到結(jié)束的狀態(tài)。這四個動畫被添加到AnimatorSet中,方便他們同時執(zhí)行。
4.當(dāng)用戶再次點擊屏幕時,動畫要執(zhí)行回去。一樣道理,給ImageView一個View.OnClickListener,然后隱藏ImageView。
private void zoomImageFromThumb(final View thumbView, int imageResId) { // 如果有動畫在執(zhí)行,立即取消,然后執(zhí)行現(xiàn)在這個動畫 if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // 加載高分辨率的圖片 final ImageView expandedImageView = (ImageView) findViewById( R.id.expanded_image); expandedImageView.setImageResource(imageResId); // 計算開始和結(jié)束位置的圖片范圍 final Rect startBounds = new Rect(); final Rect finalBounds = new Rect(); final Point globalOffset = new Point(); // 開始的范圍就是ImageButton的范圍, // 結(jié)束的范圍是容器(FrameLayout)的范圍 // getGlobalVisibleRect(Rect)得到的是view相對于整個硬件屏幕的Rect // 即絕對坐標(biāo),減去偏移,獲得動畫需要的坐標(biāo),即相對坐標(biāo) // getGlobalVisibleRect(Rect,Point)中,Point獲得的是view在它在 // 父控件上的坐標(biāo)與在屏幕上坐標(biāo)的偏移 thumbView.getGlobalVisibleRect(startBounds); findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); // Adjust the start bounds to be the same aspect ratio as the final // bounds using the "center crop" technique. This prevents undesirable // stretching during the animation. Also calculate the start scaling // factor (the end scaling factor is always 1.0). // 下面這段邏輯其實就是保持縱橫比 float startScale; // 如果結(jié)束圖片的寬高比比開始圖片的寬高比大 // 就是結(jié)束時“視覺上”拉寬了(壓扁了)圖片 if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds.width() / startBounds.height()) { // Extend start bounds horizontally startScale = (float) startBounds.height() / finalBounds.height(); float startWidth = startScale * finalBounds.width(); float deltaWidth = (startWidth - startBounds.width()) / 2; startBounds.left -= deltaWidth; startBounds.right += deltaWidth; } else { // Extend start bounds vertically startScale = (float) startBounds.width() / finalBounds.width(); float startHeight = startScale * finalBounds.height(); float deltaHeight = (startHeight - startBounds.height()) / 2; startBounds.top -= deltaHeight; startBounds.bottom += deltaHeight; } // Hide the thumbnail and show the zoomed-in view. When the animation // begins, it will position the zoomed-in view in the place of the // thumbnail. // 隱藏小的圖片,展示大的圖片。當(dāng)動畫開始的時候, // 要把大的圖片發(fā)在小的圖片的位置上 //小的設(shè)置透明 thumbView.setAlpha(0f); //大的可見 expandedImageView.setVisibility(View.VISIBLE); // Set the pivot point for SCALE_X and SCALE_Y transformations // to the top-left corner of the zoomed-in view (the default // is the center of the view). expandedImageView.setPivotX(0f); expandedImageView.setPivotY(0f); // Construct and run the parallel animation of the four translation and // scale properties (X, Y, SCALE_X, and SCALE_Y). 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; // Upon clicking the zoomed-in image, it should zoom back down // to the original bounds and show the thumbnail instead of // the expanded image. // 再次點擊返回小的圖片,就是上面擴(kuò)大的反向動畫。即預(yù)覽完成 final float startScaleFinal = startScale; expandedImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Animate the four positioning/sizing properties in parallel, // back to their original values. 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; } }); }
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- Android仿京東頂部搜索框滑動伸縮動畫效果
- Android實現(xiàn)頁面滑動切換動畫
- Android實現(xiàn)手勢滑動和簡單動畫效果
- Android程序開發(fā)之使用Design包實現(xiàn)QQ動畫側(cè)滑效果和滑動菜單導(dǎo)航
- Android編程實現(xiàn)ViewPager多頁面滑動切換及動畫效果的方法
- Android Tween動畫之RotateAnimation實現(xiàn)圖片不停旋轉(zhuǎn)效果實例介紹
- android實現(xiàn)圖片閃爍動畫效果的兩種實現(xiàn)方式(實用性高)
- Android Glide圖片加載(加載監(jiān)聽、加載動畫)
- Android圖片翻轉(zhuǎn)動畫簡易實現(xiàn)代碼
- Android實現(xiàn)ViewFlipper圖片動畫滑動
相關(guān)文章
Android滑動到頂部和底部時出現(xiàn)的陰影如何去掉
本文給大家介紹android滑動到頂部和底部時出現(xiàn)的陰影去掉的解決方法,本文還涉及到listview各個屬性的用法介紹,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧2016-10-10使用Kotlin實現(xiàn)文字漸變TextView的代碼
這篇文章主要介紹了使用Kotlin實現(xiàn)文字漸變TextView的代碼,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04RecyclerView中使用CheckBox出現(xiàn)勾選混亂的解決方法
這篇文章主要為大家詳細(xì)介紹了RecyclerView中使用CheckBox出現(xiàn)勾選混亂的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12Android Studio項目中導(dǎo)入開源庫的方法
這篇文章主要介紹了Android Studio項目中導(dǎo)入開源庫的方法,即使用第三方庫、第三廣場框架的方法,需要的朋友可以參考下2015-06-06Android 5.1 WebView內(nèi)存泄漏問題及快速解決方法
下面小編就為大家?guī)硪黄狝ndroid 5.1 WebView內(nèi)存泄漏問題及快速解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Android設(shè)置當(dāng)TextView中的文字超過TextView的容量時用省略號代替
這篇文章主要介紹了Android設(shè)置當(dāng)TextView中的文字超過TextView的容量時用省略號代替 ,需要的朋友可以參考下2017-03-03recycleview實現(xiàn)拼多多首頁水平滑動效果
這篇文章主要為大家詳細(xì)介紹了recycleview實現(xiàn)拼多多首頁水平滑動效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05