Android事件分发机制——示例(三)

版权声明:本文为博主原创文章,欢迎转载但需注明出处谢谢! https://blog.csdn.net/dongxianfei/article/details/83860512

前两篇文章我们已经分析了View和ViewGroup中通过dispatchTouchEvent进行事件分发,今天这篇文章我们通过示例来了解事件分发时的几种情况。

示例

//group
public class MyLinearLayout extends LinearLayout {
    private static String TAG = MyLinearLayout.class.getSimpleName();

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

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        Log.e(TAG, "disallowIntercept = " + disallowIntercept);
        super.requestDisallowInterceptTouchEvent(disallowIntercept);
    }
}
//child
public class MyButton extends Button {
    private static String TAG = MyButton.class.getSimpleName();

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

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<com.example.dispatchevent.MyLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.dispatchevent.MyButton
        android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="click me"/>

</com.example.dispatchevent.MyLinearLayout>
public class MainActivity extends AppCompatActivity {
    private static String TAG = "MyButton";
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = findViewById(R.id.my_button);

        mButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                int action = motionEvent.getAction();

                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        Log.e(TAG, "onTouch ACTION_DOWN");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.e(TAG, "onTouch ACTION_MOVE");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.e(TAG, "onTouch ACTION_UP");
                        break;
                    default:
                        break;
                }
                return false;
            }
        });

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "onclick");
            }
        });

        mButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Log.e(TAG, "longclick");
                return false;
            }
        });
    }
}

正确情况下的Log输出:

01-08 22:46:48.980 14659-14659/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-08 22:46:48.981 14659-14659/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-08 22:46:48.983 14659-14659/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_DOWN
01-08 22:46:48.986 14659-14659/com.example.dispatchevent E/MyButton: onTouch ACTION_DOWN
01-08 22:46:48.987 14659-14659/com.example.dispatchevent E/MyButton: onTouchEvent ACTION_DOWN

01-08 22:46:49.001 14659-14659/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
01-08 22:46:49.001 14659-14659/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE
01-08 22:46:49.001 14659-14659/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_MOVE
01-08 22:46:49.002 14659-14659/com.example.dispatchevent E/MyButton: onTouch ACTION_MOVE
01-08 22:46:49.003 14659-14659/com.example.dispatchevent E/MyButton: onTouchEvent ACTION_MOVE

01-08 22:46:49.009 14659-14659/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_UP
01-08 22:46:49.009 14659-14659/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_UP
01-08 22:46:49.009 14659-14659/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_UP
01-08 22:46:49.011 14659-14659/com.example.dispatchevent E/MyButton: onTouch ACTION_UP
01-08 22:46:49.011 14659-14659/com.example.dispatchevent E/MyButton: onTouchEvent ACTION_UP

01-08 22:46:49.037 14659-14659/com.example.dispatchevent E/MyButton: onclick

(1)onLongClick中返回不同的值

//长按会出现onClick和onLongClick都执行的情况
mButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Log.e(TAG, "longClick");
                //默认值
                return false;
            }
        });

//长按只会执行onLongClick的情况
mButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Log.e(TAG, "longClick");
                return true;
            }
        });

(2)child.onTouch中返回不同的值

//child
child.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                int action = motionEvent.getAction();

                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        Log.e(TAG, "onTouch ACTION_DOWN");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.e(TAG, "onTouch ACTION_MOVE");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.e(TAG, "onTouch ACTION_UP");
                        break;
                    default:
                        break;
                }
                return true;
				//return false;默认返回false
            }
        });

//由于onTouch返回true,导致onTouchEvent不会被执行,onClick也无法执行
01-07 04:23:35.131 14251-14251/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 04:23:35.132 14251-14251/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-07 04:23:35.132 14251-14251/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_DOWN
01-07 04:23:35.134 14251-14251/com.example.dispatchevent E/MyButton: onTouch ACTION_DOWN

01-07 04:23:35.154 14251-14251/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
01-07 04:23:35.154 14251-14251/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE
01-07 04:23:35.154 14251-14251/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_MOVE
01-07 04:23:35.156 14251-14251/com.example.dispatchevent E/MyButton: onTouch ACTION_MOVE

01-07 04:23:35.162 14251-14251/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_UP
01-07 04:23:35.162 14251-14251/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_UP
01-07 04:23:35.163 14251-14251/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_UP
01-07 04:23:35.164 14251-14251/com.example.dispatchevent E/MyButton: onTouch ACTION_UP

(3)group.onInterceptTouchEvent中返回值,事件拦截

//group
//(1)
public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return true;
        //return super.onInterceptTouchEvent(ev);默认返回值
    }
//子View事件全部被拦截,执行group.onTouchEvent
//注:在ViewGroup.onInterceptTouchEvent(ev)的ACTION_DOWN里面直接return true,导致子Vie是没有办法获得事件的
01-07 04:28:05.588 15966-15966/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 04:28:05.588 15966-15966/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-07 04:28:05.590 15966-15966/com.example.dispatchevent E/MyLinearLayout: onTouchEvent ACTION_DOWN

//(2)
public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
                return true;
                //break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

//子View的Move之后事件全部被拦截
01-07 04:31:51.459 17533-17533/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 04:31:51.459 17533-17533/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-07 04:31:51.459 17533-17533/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_DOWN
01-07 04:31:51.461 17533-17533/com.example.dispatchevent E/MyButton: onTouch ACTION_DOWN
01-07 04:31:51.461 17533-17533/com.example.dispatchevent E/MyButton: onTouchEvent ACTION_DOWN

01-07 04:31:51.481 17533-17533/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
01-07 04:31:51.481 17533-17533/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE

01-07 04:31:51.497 17533-17533/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_UP
01-07 04:31:51.498 17533-17533/com.example.dispatchevent E/MyLinearLayout: onTouchEvent ACTION_UP

(4)group.onInterceptTouchEvent中返回值,事件不拦截

//group
public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
                return true;
                //break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

//child
public boolean dispatchTouchEvent(MotionEvent event) {
		//子View照样可以接收到Move和Up事件
        getParent().requestDisallowInterceptTouchEvent(true);
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }

(5)group.dispatchTouchEvent中返回值

//group
public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return true;
        //return super.dispatchTouchEvent(ev);默认返回值
    }

//group消费了所有的事件
01-07 18:43:27.235 19366-19366/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 18:43:27.258 19366-19366/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
01-07 18:43:27.263 19366-19366/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_UP

//group
public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return false;
        //return super.dispatchTouchEvent(ev);默认返回值
}

//事件不传递了
01-07 19:01:28.472 26447-26447/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN

(6)child.dispatchTouchEvent中返回值

//child
public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return true;
        //return super.dispatchTouchEvent(event);默认返回值
    }

01-07 19:28:40.330 4815-4815/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 19:28:40.330 4815-4815/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-07 19:28:40.330 4815-4815/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_DOWN

01-07 19:28:40.358 4815-4815/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
01-07 19:28:40.359 4815-4815/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE
01-07 19:28:40.359 4815-4815/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_MOVE

01-07 19:28:40.364 4815-4815/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_UP
01-07 19:28:40.364 4815-4815/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_UP
01-07 19:28:40.364 4815-4815/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_UP

//child
public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        return false;
        //return super.dispatchTouchEvent(event);默认返回值
    }

//group.onTouchEvent处理
01-07 04:18:47.407 12087-12087/com.example.dispatchevent E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
01-07 04:18:47.407 12087-12087/com.example.dispatchevent E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
01-07 04:18:47.408 12087-12087/com.example.dispatchevent E/MyButton: dispatchTouchEvent ACTION_DOWN
01-07 04:18:47.409 12087-12087/com.example.dispatchevent E/MyLinearLayout: onTouchEvent ACTION_DOWN

猜你喜欢

转载自blog.csdn.net/dongxianfei/article/details/83860512