从此妈妈再也不用担心我的View冲突了

来源:互联网 发布:淘宝代理靠谱吗 编辑:程序博客网 时间:2024/04/28 22:27

从此妈妈再也不用担心我的View冲突了

一个APP的界面中为了达到各种炫酷的效果,舒适的体验总是多个View进行嵌套,但有的时候我们要去点击不同的View,但这时候Android系统疯了,他们都堆在一起,鬼知道你要点哪个View,所以必须有一套完善的分发机制来搞定这个问题,而我们只有了解这套分发机制,只要重写固定的几个分发,冲突也就可以迎刃而解。

只有3个方法

没错整个Android的分发机制,只有3个方法,分别是:
public boolean dispatchTouchEvent(MotionEvent ev)
public boolean onInterceptTouchEvent(MotionEvent ev)
public boolean onTouchEvent(MotionEvent ev)
这三者间的关系嘛,就好像dispatchTouchEvent是刘备,onInterceptTouchEvent是诸葛亮,onTouchEvent是关羽,前方有个郡被魏国攻击了,只要关于蜀国刘备就得处理,所以dispatchTouchEvent肯定会调用,然后刘备就会问诸葛亮(前期刘备一般是听诸葛亮的),如果诸葛亮同意打,那刘备就派关羽出战,关羽之勇自然就没那个太守什么事了,如果不同意,那就让被攻击的那个郡的太守自主防御,至于它如何调兵遣将就是它的事了,不过肯定的是它肯定也会有军师和战将。被攻击的那个郡的太守自主防御成功就没事咯,如果失败了,那还得关羽出战了。而且这个时候,刘备再也不会把防御任务交给那个郡了。
故事听晕了吧
其实质就是dispathchTouchEvent负责管理分发,onInterceptTouchEvent负责判断当前view是否拦截,如果拦截交给OnTouchEvent处理,如果不拦截交给子View的dispathchTouchEvent处理,OnTouchEvent负责处理拦截后要执行的事件。

看下实验就明白了

首先需要自定义个ViewGroup,我这里采用最简单的继承LinearLayout

package cn.edu.nuc.myviewtext;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.LinearLayout;/** * Created by lenovo on 2016/1/10. */public class MyLinearLayout  extends LinearLayout {    public static final String TAG="MyLinearLayout";    public MyLinearLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        Log.d(TAG,"调用dispatchTouchEvent");        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        Log.d(TAG,"调用onInterceptTouchEvent");        return false;    }    @Override    public boolean onTouchEvent(MotionEvent event) {        Log.d(TAG,"调用MyLinearLayout的onTouchEvent");        return super.onTouchEvent(event);    }}

然后是自定义View,我这里采用继承TextView

package cn.edu.nuc.myviewtext;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.TextView;/** * Created by lenovo on 2016/1/10. */public class MyView extends TextView {    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        Log.d(MyLinearLayout.TAG,"调用MyView的onTouchEvent");        return true;    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        Log.d(MyLinearLayout.TAG,"调用MyView的dispatchTouchEvent");        return super.dispatchTouchEvent(event);    }}

Activity更简单

package cn.edu.nuc.myviewtext;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}

布局文件

<?xml version="1.0" encoding="utf-8"?><cn.edu.nuc.myviewtext.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="cn.edu.nuc.myviewtext.MainActivity">    <cn.edu.nuc.myviewtext.MyView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Hello World!"        android:textSize="50dp"/></cn.edu.nuc.myviewtext.MyLinearLayout>

需要做的实验有:将MyLinearLayout的onInterceptTouchEvent方法设置为false,然后分别将MyView的onTouchEvent设置为true和false,MyView的onTouchEvent设置为flase的时候然后再将MyLinearLayout的onTouchEvent设置为true和false查看有什么区别。
然后将MyLinearLayout的onInterceptTouchEvent设置为true,然后将MyLinearLayout的onTouchEvent分别设置为true和false查看有什么区别。
一共是6个实验,相信大家看到6个实验的结果,就会对View冲突全部理解,而且注意测试的时候不要用点击,要用滑动测试,会有不同的效果

补充

重写View和ViewGroup的时候,如果要在xml文件中使用的话,必须要重写2个参数的构造函数。

0 0
原创粉丝点击