View的相关问题
2016-04-20 18:51
309 查看
1.如果某个view 处理事件的时候 没有消耗down事件 会有什么结果?
假如一个view,在down事件来的时候 他的onTouchEvent返回false, 那么这个down事件 所属的事件序列 就是他后续的move 和up 都不会给他处理了,全部都给他的父view处理。
此时在控制台打印出了一次onTouch
如果onTouchEvent返回true,我们看看什么效果
控制台此次打印了两次onTouch,因为我们的Action UP也执行了,所以会打印两次。
滑动冲突问题如何解决 思路是什么
答。要解决滑动冲突 其实最主要的就是有一个核心思想。你到底想在一个事件序列中,让哪个view 来响应你的滑动?比如 从上到下滑,是哪个view来处理这个事件,从左到右呢?
用业务需求 来想明白以后 剩下的 其实就很好做了。核心的方法 就是2个 外部拦截也就是父亲拦截,另外就是内部拦截,也就是子view拦截法。 学会这2种 基本上所有的滑动冲突
都是这2种的变种,而且核心代码思想都一样。
外部拦截法:思路就是重写父容器的onInterceptTouchEvent即可。子元素一般不需要管。可以很容易理解,因为这和android自身的事件处理机制 逻辑是一模一样的
内部拦截法:内部拦截法稍微复杂一点,就是事件到来的时候,父容器不管,让子元素自己来决定是否处理。如果消耗了 就最好,没消耗 自然就转给父容器处理了。
子元素代码
父亲容器代码也要修改一下,其实就是保证父亲别拦截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 }
相关文章推荐
- iOS开发--"Library not found for -"错误处理
- POJ 3126 Prime Path
- Intel HD Graphics
- run loop
- linux 下安装 nginx
- 跟我学REDIS-REDIS(四)----常用数据类型之SET
- 第七周项目1(2)
- struts2 session丢失,不经意的错误
- 课后习题11.6
- MySQL远程访问权限,允许远程连接的开启
- JDK帮助文档无法打开的常见问题和解决办法
- 二叉树的前中后序遍历
- runtime 使用
- 哈夫曼数与哈夫曼编码
- POJ 1426 Find The Mutiple
- python 处理命令行参数
- Swift之 ? , !, as
- 版本管理神器git上手
- java中的clone
- iOS代理设计模式