创建视图
layout/activity_zoom.xml
<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
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>
放大缩放试图
- 计算的起始和终止的ImageView的界限。
- 将高分辨隐藏为缩小的图
- 动画的同时定位四个的尺寸X,Y,(scale_x,和scale_y),从开始到结束的范围界限。这四个动画添加到animatorset以便他们可以在同一时间开始。
- 通过运行类似的动画来缩小图像,但当用户在放大图像时触摸屏幕时会反向显示。你可以通过添加一个view.onclicklistener到ImageView。当点击,ImageView最小化回到图像缩略图的大小和设置要去隐藏它的能见度。
src/ZoomActivity.java
public class ZoomActivity extends FragmentActivity {
//持有当前参考动画,以便可以取消中途它
private Animator mCurrentAnimator;
private int mShortAnimationDuration;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zoom);
final View thumbView = findViewById(R.id.thumb_button_1);
thumbView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
zoomImageFromThumb(thumbView,R.drawable.image_black_002);
}
});
mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
private void zoomImageFromThumb(final View thumbView,int imageResId){
//如果有一个动画正在进行,立即取消它并且继续上一个
if(mCurrentAnimator!=null){
mCurrentAnimator.cancel();
}
//加载高分辨率的"zoomed-in"image
final ImageView expandedImageView = (ImageView) findViewById(R.id.expanded_image);
expandedImageView.setImageResource(imageResId);
//为"zoomed-in"image计算开始和结束,这一步涉及很多数学
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
//全局偏移
final Point globalOffset = new Point();
thumbView.getGlobalVisibleRect(startBounds);
findViewById(R.id.container)
.getGlobalVisibleRect(finalBounds,globalOffset);
startBounds.offset(-globalOffset.x,-globalOffset.y);
finalBounds.offset(-globalOffset.x,-globalOffset.y);
//使用"center crop"技术调整起始边界与最终边界相同的宽高比。
// 这可以防止不良拉伸在动画。还计算开始缩放
float startScale;
if((float)finalBounds.width()/finalBounds.height()
>(float)startBounds.width()/startBounds.height()){
//水平展开边界
startScale = (float) startBounds.height()/finalBounds.height();
float startWidth = startScale*finalBounds.width();
float deltaWidth = (startWidth-startBounds.width())/2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
//垂直展开边界
startScale = (float)startBounds.width()/finalBounds.width();
float startHeigh = startScale*finalBounds.height();
float deltaHeigh = (startHeigh - startBounds.height())/2;
startBounds.top -= deltaHeigh;
startBounds.bottom += deltaHeigh;
}
//隐藏缩略图并在视图中显示缩放。
// 当动画开始时,它会将缩放视图放在缩略图的位置
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);
//设置scale_x和scale_y变换的放大视图左上角的中心点(默认视图的中心)。
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);
//构建和运行平行动画四个平移和缩放属性(x,y,scale_x,和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 onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
//点击放大后的图像,它应该缩小回原来的界限,
// 并显示缩略图,而不是扩大图像
final float startScaleFinal = startScale;
expandedImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
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;
}
});
}
}