一、触摸缩放

1.1 监听触摸事件

ImageView imageView = holder.photoid;
imageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        handleTouch(imageView, x, y);
        return true;
    }
});

1.2 处理触摸事件

private boolean isScale = false;

private void handleTouch(ImageView imageView, float x, float y) {
    float pivotX = x;
    float pivotY = y;
    
    if (!isScale) {
        // 开始放大动画
        imageView.setPivotX(pivotX);
        imageView.setPivotY(pivotY);
        imageView.animate()
                .scaleX(3.5f)
                .scaleY(3.5f)
                .setDuration(300)
                .start();
        isScale = true;
    } else {
        // 开始缩小动画
        imageView.setPivotX(pivotX);
        imageView.setPivotY(pivotY);
        imageView.animate()
                .scaleX(1f)
                .scaleY(1f)
                .setDuration(300)
                .start();
        isScale = false;
    }
}

二、缩放移动中心

2.1 监听触摸事件

与触摸缩放类似,首先设置触摸监听器。

imageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        handleTouchAndMove(imageView, x, y);
        return true;
    }
});

2.2 处理触摸事件并移动中心

private void handleTouchAndMove(ImageView imageView, float x, float y) {
    float pivotX = x;
    float pivotY = y;
    
    if (!isScale) {
        // 开始放大动画
        imageView.setPivotX(pivotX);
        imageView.setPivotY(pivotY);
        imageView.animate()
                .scaleX(3.5f)
                .scaleY(3.5f)
                .setDuration(300)
                .withEndAction(new Runnable() {
                    @Override
                    run() {
                        moveImageToCenter(imageView, pivotX, pivotY);
                    }
                })
                .start();
        isScale = true;
    } else {
        // 开始缩小动画
        imageView.setPivotX(pivotX);
        imageView.setPivotY(pivotY);
        imageView.animate()
                .scaleX(1f)
                .scaleY(1f)
                .setDuration(300)
                .start();
        isScale = false;
    }
}

private void moveImageToCenter(ImageView imageView, float pivotX, float pivotY) {
    float deltaX = (imageView.getWidth() / 2 - pivotX) * (3.5f - 1);
    float deltaY = (imageView.getHeight() / 2 - pivotY) * (3.5f - 1);
    
    imageView.setTranslationX(deltaX);
    imageView.setTranslationY(deltaY);
}

三、网络图片加载与放大

3.1 使用Glide加载图片

首先,在项目中引入Glide库。

dependencies {
    implementation 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
}
Glide.with(context)
        .load(url)
        .into(imageView);

3.2 点击图片放大

imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(context, PicturePreviewActivity.class);
        intent.putExtra("url", url);
        context.startActivity(intent);
    }
});
public class PicturePreviewActivity extends Activity {
    private ZoomImageView zoomView;
    private String url;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_picture_preview);
        
        url = getIntent().getStringExtra("url");
        zoomView = findViewById(R.id.zoomImageView);
        
        Glide.with(this)
                .load(url)
                .into(zoomView);
    }
}

四、总结