横向ListView中嵌套ListView
2016-01-30 08:04
399 查看
最近有个需求,横向列表中,每项又是一个垂直列表。在HorizontalListView的Adapter中使用Listview后,HorizontalListView不能左右滑动。
1,解决这个问题,先来看几个基础的方法:,
View类中:
ViewGroup类中:注意加粗有下划线的部分的内容
2,测试代码
HorizontalListView每个item为ListView,ListView的每个Item为TextView,Touch事件分发过程为:
3,我们再来看View类中的方法:
当子类调用请求父类拦截时,主要最开始标红色部分的说明。在下一个Touch事件,父控件会直接交给自己的onTouchEvent处理。
4,所以,为了满足需求我们做如下改造:
自定义MyListView类,修改的地方为:定义手势检测,横向滑动不处理
MyHorizontalListView的改动:
5,再来看Touch分发流程:
冲突解决。
1,解决这个问题,先来看几个基础的方法:,
View类中:
/** * Pass the touch screen motion event down to the target view, or this * view if it is the target. * * @param event The motion event to be dispatched. * @return True if the event was handled by the view, false otherwise. */ public boolean dispatchTouchEvent(MotionEvent event) {
@Override public boolean onTouchEvent(MotionEvent event) {
/** * {@inheritDoc} */ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
ViewGroup类中:注意加粗有下划线的部分的内容
/** * Implement this method to intercept all touch screen motion events. This * allows you to watch events as they are dispatched to your children, and * take ownership of the current gesture at any point. * * <p>Using this function takes some care, as it has a fairly complicated * interaction with {@link View#onTouchEvent(MotionEvent) * View.onTouchEvent(MotionEvent)}, and using it requires implementing * that method as well as this one in the correct way. Events will be * received in the following order: * * <ol> * <li> You will receive the down event here. * <li> The down event will be handled either by a child of this view * group, or given to your own onTouchEvent() method to handle; this means * you should implement onTouchEvent() to return true, so you will * continue to see the rest of the gesture (instead of looking for * a parent view to handle it). Also, by returning true from * onTouchEvent(), you will not receive any following * events in onInterceptTouchEvent() and all touch processing must * happen in onTouchEvent() like normal. * <li> For as long as you return false from this function, each following * event (up to and including the final up) will be delivered first here * and then to the target's onTouchEvent(). * <li> If you return true from here, you will not receive any * following events: the target view will receive the same event but * with the action {@link MotionEvent#ACTION_CANCEL}, and all further * events will be delivered to your onTouchEvent() method and no longer * appear here. * </ol> * * @param ev The motion event being dispatched down the hierarchy. * <strong><u><span style="color:#ff0000;">@return Return true to steal motion events from the children and have * them dispatched to this ViewGroup through onTouchEvent(). * The current target will receive an ACTION_CANCEL event, and no further * messages will be delivered here.</span></u></strong> */ public boolean onInterceptTouchEvent(MotionEvent ev) { return false; }
2,测试代码
HorizontalListView每个item为ListView,ListView的每个Item为TextView,Touch事件分发过程为:
</pre><pre code_snippet_id="1570234" snippet_file_name="blog_20160130_7_9380784" name="code" class="html">--------- beginning of main --------- beginning of system D/DemoApp (20605): MyHorizontalListView dispatchTouchEvent:0 D/DemoApp (20605): MyHorizontalListView onInterceptTouchEvent:0 D/DemoApp (20605): MyListView dispatchTouchEvent:0 D/DemoApp (20605): MyListView onInterceptTouchEvent:0 D/DemoApp (20605): MyTextView dispatchTouchEvent:0 D/DemoApp (20605): MyTextView onTouchEvent:0 D/DemoApp (20605): MyListView onTouchEvent:0, gestureDealed:true D/DemoApp (20605): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (20605): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (20605): MyListView dispatchTouchEvent:2 D/DemoApp (20605): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (20605): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (20605): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (20605): MyListView dispatchTouchEvent:2 D/DemoApp (20605): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (20605): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (20605): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (20605): MyListView dispatchTouchEvent:2 D/DemoApp (20605): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (20605): MyHorizontalListView dispatchTouchEvent:1 D/DemoApp (20605): MyHorizontalListView onInterceptTouchEvent:1 D/DemoApp (20605): MyListView dispatchTouchEvent:1 D/DemoApp (20605): MyListView onTouchEvent:1, gestureDealed:false
3,我们再来看View类中的方法:
<pre name="code" class="html">/** * {@inheritDoc} */ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
// We're already in this state, assume our ancestors are too
return;
}
if (disallowIntercept) {
mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
} else {
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
}
// Pass it up to our parent
if (mParent != null) {
mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
}
}
当子类调用请求父类拦截时,主要最开始标红色部分的说明。在下一个Touch事件,父控件会直接交给自己的onTouchEvent处理。
4,所以,为了满足需求我们做如下改造:
自定义MyListView类,修改的地方为:定义手势检测,横向滑动不处理
private GestureDetector mGestureDetector; /** 是否忽略该滑动事件,忽略则交给父控件处理 */ private boolean ignoreEvent = false; /** 是否已经判断过滑动方向 */ private boolean checkedDirection = false; private GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { ignoreEvent = false; checkedDirection = false; return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (!checkedDirection) { checkedDirection = true; if (Math.abs(velocityX) > Math.abs(velocityY)) { ignoreEvent = true; return false; } } if(ignoreEvent){ return false; } return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!checkedDirection) { checkedDirection = true; if (Math.abs(distanceX) > 3 && Math.abs(distanceX) > Math.abs(distanceY)) { ignoreEvent = true; return false; } } if(ignoreEvent){ return false; } return true; } };
@Override public boolean onTouchEvent(MotionEvent ev) { boolean gestureDealed = mGestureDetector.onTouchEvent(ev); GyLog.d(TAG, "onTouchEvent:" + ev.getAction() +", gestureDealed:"+gestureDealed); if(checkedDirection && ignoreEvent){ requestDisallowInterceptTouchEvent(!ignoreEvent); } if (!gestureDealed) { return false; } return super.onTouchEvent(ev); } @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { GyLog.d(TAG, "requestDisallowInterceptTouchEvent:" + disallowIntercept); super.requestDisallowInterceptTouchEvent(disallowIntercept); ViewParent parent = getParent(); while (parent != null){ parent.requestDisallowInterceptTouchEvent(disallowIntercept); parent = parent.getParent(); } }
MyHorizontalListView的改动:
/** 是否拦截touch事件 */ private boolean interceptTouchEvent = false; @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { GyLog.d(TAG, "requestDisallowInterceptTouchEvent:" + disallowIntercept); interceptTouchEvent = !disallowIntercept; super.requestDisallowInterceptTouchEvent(disallowIntercept); }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { GyLog.d(TAG, "onInterceptTouchEvent:"+ ev.getAction()); if(ev.getAction() == MotionEvent.ACTION_DOWN){ interceptTouchEvent = false; } return interceptTouchEvent; // return super.onInterceptTouchEvent(ev); }
5,再来看Touch分发流程:
D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:0 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:0 D/DemoApp (28089): MyListView dispatchTouchEvent:0 D/DemoApp (28089): MyListView onInterceptTouchEvent:0 D/DemoApp (28089): MyTextView dispatchTouchEvent:0 D/DemoApp (28089): MyTextView onTouchEvent:0 D/DemoApp (28089): MyListView onTouchEvent:0, gestureDealed:true D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:2 D/DemoApp (28089): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:2 D/DemoApp (28089): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:2 D/DemoApp (28089): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:2 D/DemoApp (28089): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:2 D/DemoApp (28089): MyListView onTouchEvent:2, gestureDealed:false D/DemoApp (28089): MyListView requestDisallowInterceptTouchEvent:false D/DemoApp (28089): MyHorizontalListView requestDisallowInterceptTouchEvent:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onInterceptTouchEvent:2 D/DemoApp (28089): MyListView dispatchTouchEvent:3 D/DemoApp (28089): MyListView onTouchEvent:3, gestureDealed:false D/DemoApp (28089): MyListView requestDisallowInterceptTouchEvent:false D/DemoApp (28089): MyHorizontalListView requestDisallowInterceptTouchEvent:false D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:2 D/DemoApp (28089): MyHorizontalListView onTouchEvent:2 D/DemoApp (28089): MyHorizontalListView dispatchTouchEvent:1 D/DemoApp (28089): MyHorizontalListView onTouchEvent:1
冲突解决。
相关文章推荐
- OSChina 周六乱弹 —— 名不副实的菜
- 开发效率之找自己顺手的利器/那些年的开发工具与习惯[利刃篇]
- JavaSE021_数组之应用举例(利用二维数组实现五子棋图形版——二人对战)
- 博客营销未死,日引万级IP
- Leetcode 159 Longest Substring with At Most Two Distinct Characters
- Leetcode 249 Group Shifted Strings
- 【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
- Window下的dos环境下编译运行下运行c程序
- Leetcode 314 Binary Tree Vertical Order Traversa
- Leetcode 274. H-Index
- Leetcode 299 Bulls and Cows
- 夺命雷公狗---微信开发18----删除自定义菜单
- tkinter的GUI设计:界面与逻辑分离(二)-- 菜单栏
- 夺命雷公狗---微信开发17----自定义菜单的事件推送,响应菜单的CLICK
- 数据挖掘博客收集
- localStorage
- linux shell编程零基础入门
- Broken Code
- canvas
- 夺命雷公狗---微信开发16----自定义菜单的查询