计算机知识

当前位置:澳门新葡萄京 > 计算机知识 > 实现ListView能滚动时则让ListView处理

实现ListView能滚动时则让ListView处理

来源:http://www.hhmtch.com 作者:澳门新葡萄京 时间:2020-03-14 00:09

外层ScrollView,内嵌ListView,都是垂直方向。采用内部拦截法,实现ListView能滚动时则让ListView处理,当ListView滑到顶部或者底部不能滑动时让ScrollView处理

图片 1

布局上面有一段文本,中间是ListView,下面还有一段文本

<?xml version="1.0" encoding="utf-8"?><org.icegeneral.scroll.MyScrollView xmlns:andro android: android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="AAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAAnAAAAAAAAAA" /> <org.icegeneral.scroll.MyListView android: android:layout_width="match_parent" android:layout_height="500dp" android:background="#888888"> </org.icegeneral.scroll.MyListView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBBnBBBBBBBBBB" /> </LinearLayout></org.icegeneral.scroll.MyScrollView>

MyScrollViewACTION_DOWN必须让给ListView,ListView才能收到ACTION_MOVE,ListView才能判断自己是否还能滚动第二点要注意的是:因为ACTION_DOWN让给ListView,那么ACTION_DOWN就无法进入ScrollView的onTouchEvent, 但是ScrollView的滚动需要在ACTION_DOWN阶段做一些准备,所以主动调用了一次

public class MyScrollView extends ScrollView { public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onTouchEvent; return false; } return true; }}

MyListView

public class MyListView extends ListView { public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } private float lastY; @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { getParent().getParent().requestDisallowInterceptTouchEvent; } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { if (lastY > ev.getY { // 如果是向上滑动,且不能滑动了,则让ScrollView处理 if (!canScrollList { getParent().getParent().requestDisallowInterceptTouchEvent; return false; } } else if  > lastY) { // 如果是向下滑动,且不能滑动了,则让ScrollView处理 if (!canScrollList { getParent().getParent().requestDisallowInterceptTouchEvent; return false; } } } lastY = ev.getY(); return super.dispatchTouchEvent; }}

Activity

protected void onCreate(Bundle savedInstanceState) { .... scrollView.smoothScrollTo;}

ACTION_DOWN的特殊性解释下为什么ListView的ACTION_UP无需调用getParent().getParent().requestDisallowInterceptTouchEvent来看下ViewGroup源码

@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) { ... boolean handled = false; if (onFilterTouchEventForSecurity { final int action = ev.getAction(); final int actionMasked = action & MotionEvent.ACTION_MASK; if (actionMasked == MotionEvent.ACTION_DOWN) { cancelAndClearTouchTargets; resetTouchState(); //重点是这句 } // Check for interception. final boolean intercepted; if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent; ev.setAction; // restore action in case it was changed } else { intercepted = false; } } else { intercepted = true; } ... } ...}private void resetTouchState() { clearTouchTargets(); resetCancelNextUpFlag; mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT; //移除FLAG_DISALLOW_INTERCEPT mNestedScrollAxes = SCROLL_AXIS_NONE;}

所以如果是ACTION_DOWN,会调用resetTouchState(),移除FLAG_DISALLOW_INTERCEPT,所以ACTION_DOWN时,parent一定会进入onInterceptTouchEvent

其他其实现在都用RecyclerView代替ListView,ScrollView嵌套RecyclerView时,对于手势已经支持得很好,不必自己处理冲突。这个在demo里也有写,做个对比

代码

本文由澳门新葡萄京发布于计算机知识,转载请注明出处:实现ListView能滚动时则让ListView处理

关键词: 冲突 嵌套 手势

上一篇:Android应用中的图片不仅包括

下一篇:没有了