參考: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上擴大顯示出來。
<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后的圖片版本。 動畫沒有發生之前,它占據了整個屏幕。動畫開始,這個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.設置zoom動畫
在ImageButton上設置點擊事件,執行zoom動畫
public class ZoomActivity extends FragmentActivity {
// 保存下當前動畫類,以便可以隨時結束動畫
private Animator mCurrentAnimator;
//系統的短時長動畫持續時間(單位ms)
// 對于不易察覺的動畫或者頻繁發生的動畫
// 這個動畫持續時間是最理想的
private int mShortAnimationDuration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zoom);
// 給ImageButton設置點擊事件
final View thumb1View = findViewById(R.id.thumb_button_1);
thumb1View.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//執行zoom動畫方法
zoomImageFromThumb(thumb1View, R.drawable.image1);
}
});
//取回系統默認的短時長動畫持續時間
mShortAnimationDuration = getResources().getInteger(
android.R.integer.config_shortAnimTime);
}
...
}
3.實現zoom動畫
你需要把從正常大小的view到擴大以后的view這個過程作成動畫。
1.指定想要zoom的圖片給ImageView。(理想情況下,這個bitmap的大小不應該比屏幕大)
2.計算這個ImageView的開始和結束位置
3.把四個點和縮放大小的屬性同時作成動畫,從開始的狀態到結束的狀態。這四個動畫被添加到AnimatorSet中,方便他們同時執行。
4.當用戶再次點擊屏幕時,動畫要執行回去。一樣道理,給ImageView一個View.OnClickListener,然后隱藏ImageView。
private void zoomImageFromThumb(final View thumbView, int imageResId) {
// 如果有動畫在執行,立即取消,然后執行現在這個動畫
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// 加載高分辨率的圖片
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();
// 開始的范圍就是ImageButton的范圍,
// 結束的范圍是容器(FrameLayout)的范圍
// getGlobalVisibleRect(Rect)得到的是view相對于整個硬件屏幕的Rect
// 即絕對坐標,減去偏移,獲得動畫需要的坐標,即相對坐標
// getGlobalVisibleRect(Rect,Point)中,Point獲得的是view在它在
// 父控件上的坐標與在屏幕上坐標的偏移
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;
// 如果結束圖片的寬高比比開始圖片的寬高比大
// 就是結束時“視覺上”拉寬了(壓扁了)圖片
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.
// 隱藏小的圖片,展示大的圖片。當動畫開始的時候,
// 要把大的圖片發在小的圖片的位置上
//小的設置透明
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.
// 再次點擊返回小的圖片,就是上面擴大的反向動畫。即預覽完成
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;
}
});
}
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持億速云!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。