android 事件分發(fā)

android事件分發(fā)默認(rèn)流程

主要函數(shù)

  • dispatchTouchEvent
  • onInterceptTouchEvent
  • onTouchEvent

事件傳遞流程
activity---->viewgroup---->view----> viewgroup----> activity----over

下面是正常分發(fā)流程的示意圖(第一次畫不要噴)

vvvvv.png

分發(fā)總結(jié)

時間分發(fā)的方法都會返回boolean值,有三種狀態(tài) super. true false
activity dispatchTouchEvent返回false會直接走activity的onTouchEvent 然后結(jié)束

1.返回super. 就是默認(rèn)分發(fā)順序 如上圖;
2.返回true時很好理解 就是本次事件被消費掉了(onInterceptTouchEvent除外) ,意思就是沒有了 不會再繼續(xù)傳遞;
3.返回false ,view總dispatchTouchEvent 返回false攔截不會向下分發(fā)會直接回調(diào)上級控件(viewgroup)的onTouchEvent ,接下來跟正常流程走.viewgroup dispatchTouchEvent的返回false會回調(diào)activity的onTouchEvent;
4.viewgroup的onInterceptTouchEvent函數(shù)比較特殊,返回true會直接掉自己的onTouchEvent返回false的話會走正常分發(fā)流程;

代碼驗證
- ---- viewgroup
public class MLinearlayout extends LinearLayout{

    public MLinearlayout(Context context) {
        super(context);
    }

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


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        Log.i("MLinearlayout","onInterceptTouchEvent");
        return false;
//        return super.onInterceptTouchEvent(ev);


    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        Log.i("MLinearlayout","dispatchTouchEvent");
//        return true;
        return super.dispatchTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        Log.i("MLinearlayout","onTouchEvent");
        return super.onTouchEvent(event);


    }


}
/**
 * @author luki
 * @create 2018/4/19 下午2:20
 * @function :
 */

-----view

public class MImage extends AppCompatImageView {


    public MImage(Context context) {
        super(context);
    }

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



    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        Log.i("MImage--------","dispatchTouchEvent");
//        return false;
        return super.dispatchTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        Log.i("MImage--------","onTouchEvent");
        return super.onTouchEvent(event);


    }

}
--------activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    android:orientation="vertical"
    android:padding="10dp">


    <view.MLinearlayout
        android:id="@+id/m_linear"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/khaki"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_i"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是一個按鈕" />


        <view.MImage
            android:id="@+id/m_imag"
            android:layout_width="300dp"
            android:layout_height="100dp"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher" />


    </view.MLinearlayout>


</LinearLayout>



/**
 * @author luki
 * @create 2018/2/28 下午5:17
 * @function :
 */

public class ActionTestActivity extends AppCompatActivity {


    @BindView(R.id.btn_i)
    Button btnI;
    @BindView(R.id.m_linear)
    MLinearlayout mLinear;
    @BindView(R.id.m_imag)
    MImage m_imag;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_aciton);
        ButterKnife.bind(this);

        initData();

    }


    public void initData() {

        mLinear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.i("MLinearlayout","OnClickListener");

            }
        });

        mLinear.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("MLinearlayout","setOnTouchListener");
                return false;
            }
        });

//        btnI.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                Log.i("btn onClick","OnClickListener");
//            }
//        });
//
//        m_imag.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                Log.i("m_imag onClick","OnClickListener");
//            }
//        });
    }



補充一點viewgroup view 如果設(shè)置onTouch 事件 onTouch的回調(diào)會在onTouchEvent之前 原理可以去看 dispatchTouchEvent 方法的源碼 他們調(diào)用 有先后順序;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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