話不多說,先上圖
主要功能就是如圖中所示,點擊圖片放大,拖拽圖片縮小到列表中圖片位置處消失。
這個功能其實原理是這樣的(我猜):
- 首先點擊列表中的圖片跳轉到新的Acticity進行預覽,當然這個Activity必須是透明的;
- 跳轉的時候需要將列表圖片的屏幕位置和寬高傳遞到新Activity中;
- 新Activity中監聽touch事件,當手指下滑足夠距離的時候讓預覽圖在當前Activity中移動到第2步中的屏幕位置並將寬高縮放到列表圖片相同的狀態,最後finish新Activity(使用漸隱動畫)。
下面介紹一下關鍵代碼:
1. 獲取控件在屏幕上的位置,很簡單:
int[] location = new int[2];
view.getLocationOnScreen(location);
2. finish的時候動畫效果我使用的是ValueAnimator :
創建ValueAnimator對象(本文爲了省事兒,只做了y軸方向的拖動),所以傳入的參數是手指離開時的位置moveY, 列表中圖片的位置viewFinishY:
ValueAnimator finishAnimator = ValueAnimator.ofInt((int) moveY, viewFinishY).setDuration(200);
接下來就是在更新監聽中更新預覽view的位置和大小:
finishAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentMove = (int) animation.getAnimatedValue();
mImageView.setTranslationY(currentMove);
ViewGroup.LayoutParams layoutParams = mImageView.getLayoutParams();
int perWidth = (int) ((imgWidth - lastWidth) * (currentMove - moveY) / (viewFinishY - moveY));
layoutParams.width = lastWidth + perWidth;
mImageView.setLayoutParams(layoutParams);
int screenWidth = ScreenParams.getScreenWH(PreviewActivity.this)[0];
int targetLeft = -(screenWidth - imgWidth) / 2 + location[0];
int perLeft = (int) (targetLeft * (currentMove - moveY) / (viewFinishY - moveY));
mImageView.setTranslationX(perLeft);
}
});
finishAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
finish();
overridePendingTransition(0, R.anim.activity_zoom_close);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
finishAnimator.start();
很簡單對不對... 本人最近換了小米,發現小米的相冊也是這樣效果,故而做了個簡單的demo, 新人可以get下。