View事件分發(fā)

前言

android事件處理,最復(fù)雜的就是對(duì)Touch事件的處理,因?yàn)門ouch事件包括:down, move, up, cancle和多點(diǎn)觸摸等多種情況,多點(diǎn)觸摸的情況先不討論,因?yàn)門ouch有這么多的狀態(tài),所以Touch相對(duì)來說是最難處理的,下面就來討論一下android是如何處理Touch事件的

事件主要方法

    //分發(fā)
    //super.dispatchTouchEvent(ev) --> 將事件向上傳遞 --> 交給父容器 處理是否分發(fā)
    //true --> 不向下分發(fā) --> 不向上傳遞 --> 我自己來處理所有事件
    //false --> 不向下分發(fā) --> 向上傳遞 --> 完成父容器的事件
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("GAO", "CustomView-dispatchTouchEvent");
        return false;
    }

    //攔截
    //return true 進(jìn)行攔截 --> 不向下給子控件傳遞事件
    //return false 不進(jìn)行攔截
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e("GAO", "CustomView-onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }

    //所有觸摸事件
    //按下
    //移動(dòng)
    //抬起
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("GAO", "CustomView-onTouchEvent");
        return super.onTouchEvent(event);
    }

進(jìn)行事件攔截走向測試

    <com.mine.touchdemo.CustomLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.mine.touchdemo.CustomView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.mine.touchdemo.CustomTextView
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </com.mine.touchdemo.CustomView>

    </com.mine.touchdemo.CustomLayout>

默認(rèn)事件打印

2020-01-07 16:02:38.312 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomView-onInterceptTouchEvent
2020-01-07 16:02:38.313 24136-24136/com.mine.touchdemo E/GAO: CustomTextView-onInterceptTouchEvent
2020-01-07 16:02:38.315 24136-24136/com.mine.touchdemo E/GAO: CustomTextView-onInterceptTouchEvent
2020-01-07 16:02:38.315 24136-24136/com.mine.touchdemo E/GAO: CustomView-onTouchEvent
2020-01-07 16:02:38.316 24136-24136/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent

dispatchTouchEvent return true

2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:16:18.484 24839-24839/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent

dispatchTouchEvent return false

2020-01-07 16:17:29.689 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:17:29.689 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:17:29.690 25066-25066/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:17:29.691 25066-25066/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent

onInterceptTouchEvent return true

2020-01-07 16:18:57.270 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-dispatchTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-onInterceptTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomView-dispatchTouchEvent
2020-01-07 16:18:57.271 25291-25291/com.mine.touchdemo E/GAO: CustomView-onInterceptTouchEvent
2020-01-07 16:18:57.272 25291-25291/com.mine.touchdemo E/GAO: CustomView-onTouchEvent
2020-01-07 16:18:57.272 25291-25291/com.mine.touchdemo E/GAO: CustomLayout-onTouchEvent

Fragment 添加下拉刷新 Demo

public class FragmentRefreshLayout extends FrameLayout {


    private LinearLayout mRefreshLayout;
    private LinearLayout mMainLayout;

    private int mMaxRefreshHeight = 200;

    private PointF mBeforePointF;


    public FragmentRefreshLayout(Context context) {
        super(context);
        initView();
        initData();
    }

    public FragmentRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
        initData();
    }

    private void initView() {
        setBackgroundColor(Color.GRAY);

        mMainLayout = new LinearLayout(getContext());
        LayoutParams mainParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mMainLayout.setLayoutParams(mainParams);
        mMainLayout.setBackgroundColor(Color.WHITE);

        mRefreshLayout = new LinearLayout(getContext());
        LayoutParams refreshParams = new LayoutParams(LayoutParams.MATCH_PARENT, mMaxRefreshHeight);
        refreshParams.topMargin = -mMaxRefreshHeight;
        mRefreshLayout.setLayoutParams(refreshParams);
        mRefreshLayout.setBackgroundColor(Color.RED);

        addView(mRefreshLayout);
        addView(mMainLayout);
    }

    private void initData() {
        mBeforePointF = new PointF();
    }

    //分發(fā)事件
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            mBeforePointF.x = ev.getX();
            mBeforePointF.y = ev.getY();
        } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            //偏移量
            float xDimension = Math.abs(ev.getX() - mBeforePointF.x);
            float yDimension = Math.abs(ev.getY() - mBeforePointF.y);
            //判讀滑動(dòng)方向
            if (xDimension > yDimension * 1.5) {
                //X軸滑動(dòng)
                return super.dispatchTouchEvent(ev);
            }
            //最小響應(yīng)距離
            if (yDimension < 5) {
                return super.dispatchTouchEvent(ev);
            }
            //可滑動(dòng)范圍
            //Main下拉
            LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
            if (mainParams.topMargin < 0) {
                mainParams.topMargin = 0;
            }
            if (mainParams.topMargin > mMaxRefreshHeight) {
                mainParams.topMargin = mMaxRefreshHeight;
            }
            mainParams.topMargin += ev.getY() - mBeforePointF.y;
            mMainLayout.setLayoutParams(mainParams);
            requestLayout();
            mBeforePointF.x = ev.getX();
            mBeforePointF.y = ev.getY();
        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            //當(dāng)滑動(dòng)位置,打開或關(guān)閉
            LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
            if (mainParams.topMargin < 100) {
                startAnim(mainParams.topMargin, 0);
            } else {
                startAnim(mainParams.topMargin, mMaxRefreshHeight);
            }
        }
        return true;
    }

    private void startAnim(int start, int end) {
        ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
        valueAnimator.setDuration(500);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                LayoutParams mainParams = (LayoutParams) mMainLayout.getLayoutParams();
                mainParams.topMargin = (int) animation.getAnimatedValue();
                mMainLayout.setLayoutParams(mainParams);
                requestLayout();
            }
        });
        valueAnimator.start();
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容