解决 ScrollView 嵌套 ListView 时,高度不正常和滑动冲突的问题
来源:互联网 发布:诸暨淘宝拍卖资产 编辑:程序博客网 时间:2024/05/08 10:51
我们在用ScrollView嵌套ListView会两个问题,一个问题是ListView高度不正常,另外一个问题是ListView无法滑动。下面我们就来看看这两个问题怎么解决吧。
第一个问题
ListView只能显示一个Item高度的问题。因为ScrollView在测量ChildView的时候,强制把ChildView的MeasureSpec模式更改为MeasureSpec.UNSPECIFIED,而我们通过查看ListView的onMeasure方法可以发现
if (heightMode == MeasureSpec.UNSPECIFIED) { heightSize = mListPadding.top + mListPadding.bottom + childHeight + getVerticalFadingEdgeLength() * 2; }
当heightMode为MeasureSpec.UNSPECIFIED时,ListView的高度会被设置为上下的padding加上一个childView的高度,所以就会出现只显示一个Item高度的问题。
那我们怎么解决呢?
第一种方法,我们可以重写ListView,在onMeasure的时候重新设置高度的MeasureSpec模式。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // MeasureSpec的前两位是模式,所以需要右移两位。 heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpec); }这样ListView就是完全展开的状态了。
第二种方法,我们可以在布局里面为ScollView加一个
android:fillViewport="true"这样ScrollView就会被强制要求测量ChildView并设置模式MeasureSpec.EXACTLY,所以ListView会完全展开。
第二个问题
ScrollView嵌套ListView时,一般我们有两种需求
第一种是ListVIew完全伸展并跟随ScrollView一起滑动,那只要按照上面的解决了伸展的问题, 就实现这种效果了,因为ScrollView默认是拦截ListView的滑动事件的。
第二种是ScrollView不拦截滑动事件,当我们在ListView区域滑动时,由ListView处理滑动事件,只有在ListView已到达顶部还继续向上滑或者ListView已到达底部还继续向下滑时才重新拦截滑动事件。而当我们在非ListView区域滑动时,则直接由ScrollView处理滑动事件,那么我们看看怎么实现这种效果。
首先,我们先了解为什么ListView无法获取到滑动事件,我们先看一下ScrollView的onInterceptTouchEvent方法
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) { return true; }省略 //........}不重要的部分被我省略了,mIsBeingDragged是最小滑动像素,超过这个值才被认为是发生滑动了。那从上面的代码我们可以看出的,当发生滑动的第一时间,事件就被ScrollView拦截了,所以ListView不能滑动
但是我们注意到,在MotionEvent.ACTION_MOVE之前是会产生一个MotionEvent.ACTION_DOWN的,那么这个事件是没有被拦截的,并且在滑动未超过最小像素之前,
MotionEvent.ACTION_MOVE也是未被拦截的,那么其实我们是可以在ListView里面接收到MotionEvent.ACTION_DOWN和几个MotionEvent.ACTION_MOVE的。
既然如此,那我们在自定义ListView里面请求ScrollView不要拦截事件不就好了吗。
public class MyListview extends ListView{ private ScrollView mParent; private float mDownY; public MyListview(Context context) { super(context); } public MyListview(Context context, AttributeSet attrs) { super(context, attrs); } public MyListview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setParent(ScrollView view){ mParent = view; } //重写该方法 在按下的时候让父容器不处理滑动事件 @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: setParentScrollAble(false); mDownY = ev.getY(); break; case MotionEvent.ACTION_MOVE: // if (isListViewReachTop() && ev.getY() - mDownY > 0) { setParentScrollAble(true); } else if (isListViewReachBottom() && ev.getY() - mDownY < 0) { setParentScrollAble(true); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: setParentScrollAble(true); break; default: break; } return super.onTouchEvent(ev); } /** * @param flag */ private void setParentScrollAble(boolean flag) { mParent.requestDisallowInterceptTouchEvent(!flag); } public boolean isListViewReachTop() { boolean result=false; if(getFirstVisiblePosition()==0){ View topChildView = getChildAt(0); if (topChildView != null) { result=topChildView.getTop()==0; } } return result ; } public boolean isListViewReachBottom() { boolean result=false; if (getLastVisiblePosition() == (getCount() - 1)) { View bottomChildView = getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()); if (bottomChildView != null) { result= (getHeight() >= bottomChildView.getBottom()); } } return result; }}在上面的代码中,我们首先需要把ScrollView设置进来,然后在onTouchEvent中接收到MotionEvent.ACTION_DOWN事件时,请求ScrollView不要拦截滑动事件,这样ListView就可以处理滑动事件了,而在顶部仍然向上滑和在底部仍然向下滑 和 MotionEvent.ACTION_UP 和 MotionEvent_ACTION_CANCEL时,都直接重新把事件给回ScrollView。
0 0
- 解决 ScrollView 嵌套 ListView 时,高度不正常和滑动冲突的问题
- 解决 ScrollView 嵌套 ListView 时,高度不正常和滑动冲突的问题
- 解决ScrollView嵌套ListView滑动冲突显示不全的问题
- Android ScrollView中嵌套ListView,滑动冲突问题的解决
- Android ScrollView中嵌套ListView,滑动冲突问题的解决
- 解决ScrollView中嵌套Listview,Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 【Android界面实现】解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题
- 解决 scrollview嵌套recyclerview 中不能滑动,高度不正常的问题。
- 解决ScrollView嵌套ListView显示不完全和滑动冲突的问题
- ScrollView与Listview嵌套使用时的滑动冲突问题
- 解决 ScrollView和ListView连用时的滑动冲突和显示不正常
- 解决Scrollview 嵌套recyclerview不能显示,高度不正常的问题
- 解决scrollView嵌套listview的冲突问题
- keil C中嵌入汇编程序的方法
- uploadify+批量上传文件+java
- mysql优化参考网址
- CFNetwork(二)
- 结合进程类别对Activity各个状态与方法的理解
- 解决 ScrollView 嵌套 ListView 时,高度不正常和滑动冲突的问题
- 和为S的两个数
- php excel A 列字符串替换成B列 字符串
- java 编译和加载和执行类的全过程
- 学习 Retrofit2
- Windows下使用MATLAB时几个Perl工具包的安装(XML::Twig,XML::Parser,Math::Polygon::Calc,Tie::IxHash)
- UVa465 switch语句——愿天下再无WA
- APUE2-学习-环境配置
- linux安装mysql