Android開發筆記——點選檢視大圖過渡動畫與圖片縮放與移動

renke發表於2021-09-09

從一個activity到另一個activity的過渡

1.小圖點選事件程式碼

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.img_1:
            view.setClickable(false);
            Intent intentS = new Intent(this, ImageActivity.class);
            int[] screenLocationS = new int[2];
            view.getLocationOnScreen(screenLocationS);
            intentS.putExtra(LEFT, screenLocationS[0]).//將圖片位置傳到大圖activity用於動畫初始位置
                    putExtra(TOP, screenLocationS[1]).
                    putExtra(WIDTH, view.getWidth()).
                    putExtra(HEIGHT, view.getHeight()).
                    putExtra(IMAGE, _snapUrl).
                    putExtra(TITLE, _name);
            startActivity(intentS);
            overridePendingTransition(0, 0);//取消原有預設的Activity到Activity的過渡動畫
            break;
        case R.id.img_2:
            view.setClickable(false);
            Intent intentM = new Intent(this, ImageActivity.class);
            int[] screenLocationM = new int[2];
            view.getLocationOnScreen(screenLocationM);
            intentM.putExtra(LEFT, screenLocationM[0]).//將圖片位置傳到大圖activity用於動畫初始位置
                    putExtra(TOP, screenLocationM[1]).
                    putExtra(WIDTH, view.getWidth()).
                    putExtra(HEIGHT, view.getHeight()).
                    putExtra(IMAGE, _matchUrl).
                    putExtra(TITLE, _name);
            startActivity(intentM);
            overridePendingTransition(0, 0);//取消原有預設的Activity到Activity的過渡動畫
            break;
    }
}

2.大圖Activity程式碼

public class BigImageActivity extends Activity implements View.OnClickListener {

    private static final int DURATION = 150;

    public final static String TITLE  = "Title";
    public final static String TOP    = "Top";
    public final static String LEFT   = "Left";
    public final static String WIDTH  = "Width";
    public final static String HEIGHT = "Height";
    public final static String IMAGE  = "Image";

    private int   mLeftDelta;
    private int   mTopDelta;
    private float mWidthScale;
    private float mHeightScale;

    private int           intentTop;
    private int           intentLeft;
    private int           intentWidth;
    private int           intentHeight;
    private LinearLayout  linearLayout;
    private ColorDrawable colorDrawable;
    private ImageView     imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FaceDetectionApp.setWindowTrans(this, true, false);
        setContentView(R.layout.activity_image);
        initView();
        if (savedInstanceState == null) {
            ViewTreeObserver observer = imageView.getViewTreeObserver();
            observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    imageView.getViewTreeObserver().removeOnPreDrawListener(this);
                    int[] screenLocation = new int[2];
                    imageView.getLocationOnScreen(screenLocation);
                    mLeftDelta = intentLeft - screenLocation[0];
                    mTopDelta = intentTop - screenLocation[1];

                    mWidthScale = (float) intentWidth / imageView.getWidth();
                    mHeightScale = (float) intentHeight / imageView.getHeight();
                    enterAnimation(new Runnable() {
                        @Override
                        public void run() {
                            Matrix matrix = imageView.getMatrix();
                            imageView.setImageMatrix(matrix);
                            imageView.setScaleType(ImageView.ScaleType.MATRIX);
                            imageView.setOnTouchListener(new ImageTouchListener());
                        }
                    });
                    return true;
                }
            });
        }
    }

    @Override
    protected void initView() {
        super.initView();
        linearLayout = findViewById(R.id.ll_img);
        imageView = findViewById(R.id.img);
        initValue();
    }

    @Override
    protected void initValue() {
        super.initValue();
        colorDrawable = new ColorDrawable(ContextCompat.getColor(this, R.color.color_item_background));
        linearLayout.setBackground(colorDrawable);
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            title = bundle.getString(TITLE);
            intentTop = bundle.getInt(TOP);
            intentLeft = bundle.getInt(LEFT);
            intentWidth = bundle.getInt(WIDTH);
            intentHeight = bundle.getInt(HEIGHT);
            String imgURL = bundle.getString(IMAGE);
            asyncLoadImageSmallList(imageView, imgURL);//框架程式碼 不解釋
            imageView.setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.img:
                view.setClickable(false);
                exitAnimation(new Runnable() {
                    public void run() {
                        finish();
                        overridePendingTransition(0, 0);
                    }
                });
                break;
        }
    }

    @Override
    public void onBackPressed() {
        exitAnimation(new Runnable() {
            public void run() {
                finish();
                overridePendingTransition(0, 0);
            }
        });
    }

    public void enterAnimation(final Runnable enterAction) {
        imageView.setPivotX(0);
        imageView.setPivotY(0);
        imageView.setScaleX(mWidthScale);
        imageView.setScaleY(mHeightScale);
        imageView.setTranslationX(mLeftDelta);
        imageView.setTranslationY(mTopDelta);
        TimeInterpolator sDecelerator = new DecelerateInterpolator();
        imageView.animate().setDuration(DURATION).scaleX(1).scaleY(1).
                translationX(0).translationY(0).setInterpolator(sDecelerator).withEndAction(enterAction);
        ObjectAnimator bgAnim = ObjectAnimator.ofInt(colorDrawable, "alpha", 0, 255);
        bgAnim.setDuration(DURATION);
        bgAnim.start();
    }

    public void exitAnimation(final Runnable endAction) {

        TimeInterpolator sInterpolator = new AccelerateInterpolator();
        imageView.animate().setDuration(DURATION).scaleX(mWidthScale).scaleY(mHeightScale).
                translationX(mLeftDelta).translationY(mTopDelta).setInterpolator(sInterpolator).withEndAction(endAction);

        ObjectAnimator bgAnim = ObjectAnimator.ofInt(colorDrawable, "alpha", 0);
        bgAnim.setDuration(DURATION);
        bgAnim.start();
    }
}

3.縮放與移動程式碼

public class ImageTouchListener implements View.OnTouchListener {

    private              boolean isClick   = false;
    private              int     mode      = 0;// default value
    /**
     * Drag mode
     */
    private static final int     MODE_DRAG = 1;
    /**
     * Zoom mode
     */
    private static final int     MODE_ZOOM = 2;

    /**
     * Beginning point
     */
    private PointF startPoint    = new PointF();
    private Matrix matrix        = new Matrix();
    private Matrix currentMatrix = new Matrix();

    /**
     * Distance between two fingers
     */
    private float  startDis;
    /**
     * The middle point of two fingers
     */
    private PointF midPoint;

    private float values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    private float touchX   = 0;
    private float touchY   = 0;
    private float scaleXY  = 0;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView imageView = (ImageView) v;
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                isClick = true;
                mode = MODE_DRAG;
                currentMatrix.set(imageView.getImageMatrix());
                matrix.set(currentMatrix);
                startPoint.set(event.getX(), event.getY());
                touchX = event.getX();
                touchY = event.getY();
                if (scaleXY == 0) {
                    matrix.getValues(values);
                    scaleXY = values[0];
                }
                break;
            case MotionEvent.ACTION_MOVE:
                matrix.getValues(values);
                if (mode == MODE_DRAG) {
                    float dx = event.getX() - startPoint.x;
                    float dy = event.getY() - startPoint.y;
                    if (dx > 15 || dx  15 || dy  v.getWidth() - offset1 && touchX - event.getX()  v.getHeight() - offset1 && touchY - event.getY() 
                                0)) {
                            values[5] += event.getY() - touchY;
                            touchY = event.getY();
                        }
                        matrix.setValues(values);
                        imageView.setImageMatrix(matrix);
                        return true;
                    } else if ((values[2] + width  0)) {//move to left
                        values[2] = offset1 - width - 5;
                        if (!(values[5] > v.getHeight() - offset1 && touchY - event.getY() 
                                0)) {
                            values[5] += event.getY() - touchY;
                            touchY = event.getY();
                        }
                        matrix.setValues(values);
                        imageView.setImageMatrix(matrix);
                        return true;
                    }
                    if ((values[5] > v.getHeight() - offset1 && touchY - event.getY()  v.getWidth() - offset1 && touchX - event.getX()  0)) {
                            values[2] += event.getX() - touchX;
                            touchX = event.getX();
                        }
                        matrix.setValues(values);
                        imageView.setImageMatrix(matrix);
                        return true;
                    } else if ((values[5] + height  0)) {//move to top
                        values[5] = offset2 - height - 5;
                        if (!(values[2] > v.getWidth() - offset1 && touchX - event.getX()  0)) {
                            values[2] += event.getX() - touchX;
                            touchX = event.getX();
                        }
                        matrix.setValues(values);
                        imageView.setImageMatrix(matrix);
                        return true;
                    }
                    touchX = event.getX();
                    touchY = event.getY();
                    matrix.set(currentMatrix);
                    matrix.postTranslate(dx, dy);
                } else if (mode == MODE_ZOOM) {
                    float endDis = distance(event);
                    if (endDis > 10f) {
                        float scale = endDis / startDis;
                        if (values[0] / scaleXY  3 && scale > 1) {
                            return true;
                        }
                        matrix.set(currentMatrix);
                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }
                    isClick = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isClick) {
                    v.performClick();
                }
            case MotionEvent.ACTION_POINTER_UP:
                isClick = false;
                mode = 0;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                isClick = false;
                mode = MODE_ZOOM;
                startDis = distance(event);
                if (startDis > 10f) {
                    midPoint = mid(event);
                    currentMatrix.set(imageView.getImageMatrix());
                }
                break;
        }
        imageView.setImageMatrix(matrix);
        return true;
    }

    /**
     * Calculate the distance between two fingers
     */
    private float distance(MotionEvent event) {
        float dx = event.getX(1) - event.getX(0);
        float dy = event.getY(1) - event.getY(0);
        return (float) Math.sqrt(dx * dx + dy * dy);
    }

    /**
     * calculate the middle point of the two fingers
     */
    private PointF mid(MotionEvent event) {
        float midX = (event.getX(1) + event.getX(0)) / 2;
        float midY = (event.getY(1) + event.getY(0)) / 2;
        return new PointF(midX, midY);
    }

}

4.大圖佈局檔案程式碼



    

做個筆記,留作以後,不保證編譯透過。並且部分程式碼漣源網路。

原文連結:http://www.apkbus.com/blog-184446-78285.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/430/viewspace-2806125/,如需轉載,請註明出處,否則將追究法律責任。

相關文章