ViewGroup的dispatchTouchEvent(MotionEvent ev)

package com.hochan.myapplication3;

import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;

public class ZoomViewGroup extends FrameLayout{

    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;

    private int mMode = NONE;

    // 初始的两个手指按下的触摸点的距离
    private float oriDis = 1f;

    public ZoomViewGroup(@NonNull Context context) {
        super(context);
    }

    public ZoomViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ZoomViewGroup(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                // 第一个手指按下事件
                mMode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                // 第二个手指按下事件
                oriDis = distance(event);
                if (oriDis > 10f) {
                    mMode = ZOOM;
                    // 在onInterceptTouchEvent返回true之后会往子View传MotionEvent.Cancel
                    // 之后直接调用onTouchEvent
                    return true;
                }
        }

        return false;
    }

    // 计算两个触摸点之间的距离
    private float distance(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        View view = getChildAt(0);
        // 进行与操作是为了判断多点触摸
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                // 手指放开事件
                mMode = NONE;
                view.animate().scaleX(1).scaleY(1).setDuration(200).setInterpolator(new OvershootInterpolator()).start();
                break;
            case MotionEvent.ACTION_MOVE:
                // 手指滑动事件
                if (mMode == DRAG) {
                    // 是一个手指拖动
                   return false;
                } else if (mMode == ZOOM) {
                    // 两个手指滑动
                    float newDist = distance(event);
                    if (newDist > 10f) {
                        float scale = newDist / oriDis;
                        view.setScaleX(scale);
                        view.setScaleY(scale);
                    }
                }
                break;
        }
        return true;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 又失败了 我终归明白情怀不能生出钱来才华也不会自己说话你告诉我不能被失败打败 坚强起来因为成功是失败的孩道理我都明...
    米粒mili阅读 1,885评论 0 1
  • 模式匹配 同时检查名字和密码 使用单个元组 部分匹配 只匹配元组的一部分 匹配计算型元组 遍历元组 使用 when...
    焉知非鱼阅读 2,675评论 0 1