View的相关问题

1.如果某个view 处理事件的时候 没有消耗down事件 会有什么结果?
假如一个view,在down事件来的时候 他的onTouchEvent返回false, 那么这个down事件 所属的事件序列 就是他后续的move 和up 都不会给他处理了,全部都给他的父view处理。

public class MyButton extends Button {
    private Context context;
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Toast.makeText(context, "ontouchevent", Toast.LENGTH_SHORT).show();
        return false;
    }
}
public class MainActivity extends AppCompatActivity {
    private TextView mTextView;
    private Button mBut;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBut = (Button) findViewById(R.id.textview);
        mBut.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                System.out.println("========ontouch");
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        Toast.makeText(MainActivity.this, "down", Toast.LENGTH_SHORT).show();
                        return false;
                    case MotionEvent.ACTION_UP:
                        Toast.makeText(MainActivity.this, "up", Toast.LENGTH_SHORT).show();
                    break;
                    case MotionEvent.ACTION_MOVE:
                        Toast.makeText(MainActivity.this, "move", Toast.LENGTH_SHORT).show();
                    break;
                }
                return true;
            }
        });
    }
}

这里写图片描述

此时在控制台打印出了一次onTouch

如果onTouchEvent返回true,我们看看什么效果
这里写图片描述

控制台此次打印了两次onTouch,因为我们的Action UP也执行了,所以会打印两次。

滑动冲突问题如何解决 思路是什么

答。要解决滑动冲突 其实最主要的就是有一个核心思想。你到底想在一个事件序列中,让哪个view 来响应你的滑动?比如 从上到下滑,是哪个view来处理这个事件,从左到右呢?

用业务需求 来想明白以后 剩下的 其实就很好做了。核心的方法 就是2个 外部拦截也就是父亲拦截,另外就是内部拦截,也就是子view拦截法。 学会这2种 基本上所有的滑动冲突

都是这2种的变种,而且核心代码思想都一样。

外部拦截法:思路就是重写父容器的onInterceptTouchEvent即可。子元素一般不需要管。可以很容易理解,因为这和android自身的事件处理机制 逻辑是一模一样的

@Override
 2     public boolean onInterceptTouchEvent(MotionEvent ev) {
 3 
 4         boolean intercepted = false;
 5         int x = (int) ev.getX();
 6         int y = (int) ev.getY();
 7 
 8         switch (ev.getAction()) {
 9             //down事件肯定不能拦截 拦截了后面的就收不到了
10             case MotionEvent.ACTION_DOWN:
11                 intercepted = false;
12                 break;
13             case MotionEvent.ACTION_MOVE:
14                 if (你的业务需求) {
15                     //如果确定拦截了 就去自己的onTouchEvent里 处理拦截之后的操作和效果 即可了
16                     intercepted = true;
17                 } else {
18                     intercepted = false;
19                 }
20                 break;
21             case MotionEvent.ACTION_UP:
22                 //up事件 我们一般都是返回false的 一般父容器都不会拦截他。 因为up是事件的最后一步。这里返回true也没啥意义
23                 //唯一的意义就是因为 父元素 up被拦截。导致子元素 收不到up事件,那子元素 就肯定没有onClick事件触发了,这里的
24                 //小细节 要想明白
25                 intercepted = false;
26                 break;
27             default:
28                 break;
29         }
30         return intercepted;
31     }

内部拦截法:内部拦截法稍微复杂一点,就是事件到来的时候,父容器不管,让子元素自己来决定是否处理。如果消耗了 就最好,没消耗 自然就转给父容器处理了。

子元素代码

@Override
 2     public boolean dispatchTouchEvent(MotionEvent event) {
 3         int x = (int) event.getX();
 4         int y = (int) event.getY();
 5         switch (event.getAction()) {
 6             case MotionEvent.ACTION_DOWN:
 7                 getParent().requestDisallowInterceptTouchEvent(true);
 8                 break;
 9             case MotionEvent.ACTION_MOVE:
10                 if (如果父容器需要这个点击事件) {
11                     getParent().requestDisallowInterceptTouchEvent(false);
12                 }//否则的话 就交给自己本身view的onTouchEvent自动处理了
13                 break;
14             case MotionEvent.ACTION_UP:
15                 break;
16             default:
17                 break;
18         }
19         return super.dispatchTouchEvent(event);
20     }

父亲容器代码也要修改一下,其实就是保证父亲别拦截down:

 @Override
2     public boolean onInterceptTouchEvent(MotionEvent ev) {
3 
4         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
5             return false;
6 
7         }
8         return true;
9     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值