ScrollView嵌套GridView、ListView的那些事儿
2017-02-13 10:45
501 查看
,尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/55045748, 本文出自:【gengqiquan的博客】
在android开发中,经常有一些UI需要进行固定style的动态布局,然而由于现在的UI都喜欢把一个界面拉的很长,所以我们很多情况下需要使用ScrollView来嵌套列表控件来实现UI。这样就导致了很多不顺心的问题。
有两种解决方案
方案一
在适配器赋值完成后代码动态计算列表的高度。这里贴出ListView的计算代码,GridView的计算方式类似,不过需要考虑列数,下面代码没有加上列表控件padding的计算,如果你设置了这个属性,需要加上计算代码
方案二
重写列表控件的onMeasure方法,这种方案不会出现列表控件本身的滚动条,并且viewholder复用机制会失效
方案一代码多,需要多次写,建议写成工具类方便调用;方案二在数据量大到不能一屏显示完的情况下会有性能问题,而且快速滑动的时候ScrollView会不停的去计算列表控件的高度。贼影响绘制性能。
两种方案有利有弊,大家自己取舍
方案一
等待列表控件数据全部加载完成后(包括图片加载)调用ScrollView.fullScroll(ScrollView.FOCUS_UP);
方法让ScrollView滚动到顶部。这个加载完成的时间不好控制,搞得不好会有滚动动画出现,很尴尬的事情。
方案二
重写列表控件的如下两个方法,使之固定返回false
两种方案的优缺点很明显,喔,第二种方案的缺点我目前没发现。如果你这么使用发现了什么坑,请留言告知
解决起来也离不开几个要点,不过首先你得熟悉view的事件传递
你需要根据情况决定重写列表控件与ScrollView的如下几个方法,根据情况给方法返回不同的bool值来告诉控件是否拦截或者传递事件,需要哪个控件相应哪个方向的滚动事件就拦截哪个方向的事件传递,作为一个有追求的开发者,切记不要一通乱拦截
给个小彩蛋
这一句代码可以在子控件里决定是否让父容器获取事件
有什么建议的可以留言喔
如果我的博客对您有帮助,请留言鼓励下或者点个赞吧!
我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。
在android开发中,经常有一些UI需要进行固定style的动态布局,然而由于现在的UI都喜欢把一个界面拉的很长,所以我们很多情况下需要使用ScrollView来嵌套列表控件来实现UI。这样就导致了很多不顺心的问题。
问题一:列表控件显示不完全
原因是嵌套情况下,ScrollView不能正确的计算列表控件的高度。有两种解决方案
方案一
在适配器赋值完成后代码动态计算列表的高度。这里贴出ListView的计算代码,GridView的计算方式类似,不过需要考虑列数,下面代码没有加上列表控件padding的计算,如果你设置了这个属性,需要加上计算代码
public void setListViewHeightBasedOnChildren(ListView listView) { // 获取ListView对应的Adapter ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return; } int totalHeight = 0; for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目 View listItem = listAdapter.getView(i, null, listView); // 计算子项View 的宽高 listItem.measure(0, 0); // 统计所有子项的总高度 totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight+ (listView.getDividerHeight() * (listAdapter.getCount() - 1)); // listView.getDividerHeight()获取子项间分隔符占用的高度 // params.height最后得到整个ListView完整显示需要的高度 listView.setLayoutParams(params); }
方案二
重写列表控件的onMeasure方法,这种方案不会出现列表控件本身的滚动条,并且viewholder复用机制会失效
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(1 << 16, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }
方案一代码多,需要多次写,建议写成工具类方便调用;方案二在数据量大到不能一屏显示完的情况下会有性能问题,而且快速滑动的时候ScrollView会不停的去计算列表控件的高度。贼影响绘制性能。
两种方案有利有弊,大家自己取舍
问题二:列表控件自动获取焦点,导致ScrollView自动滚动到列表控件所在的位置
这个问题其实有很多种解决方案,归结起来是两种。方案一
等待列表控件数据全部加载完成后(包括图片加载)调用ScrollView.fullScroll(ScrollView.FOCUS_UP);
方法让ScrollView滚动到顶部。这个加载完成的时间不好控制,搞得不好会有滚动动画出现,很尴尬的事情。
方案二
重写列表控件的如下两个方法,使之固定返回false
@Override public boolean isFocused() { return false; } @Override public boolean requestFocus(int direction, Rect previouslyFocusedRect) { return false; }
两种方案的优缺点很明显,喔,第二种方案的缺点我目前没发现。如果你这么使用发现了什么坑,请留言告知
问题三 滑动冲突
这问题就更操蛋了,根据UI的不同,操蛋程度也不同,涉及到view的事件传递知识,很难给出所有情况的解决代码解决起来也离不开几个要点,不过首先你得熟悉view的事件传递
你需要根据情况决定重写列表控件与ScrollView的如下几个方法,根据情况给方法返回不同的bool值来告诉控件是否拦截或者传递事件,需要哪个控件相应哪个方向的滚动事件就拦截哪个方向的事件传递,作为一个有追求的开发者,切记不要一通乱拦截
@Override public boolean onTouchEvent(MotionEvent ev) { return super.onTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); }
给个小彩蛋
getParent().requestDisallowInterceptTouchEvent(boolean b);
这一句代码可以在子控件里决定是否让父容器获取事件
有什么建议的可以留言喔
如果我的博客对您有帮助,请留言鼓励下或者点个赞吧!
我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。
相关文章推荐
- 完美解决ScrollView嵌套ListView或GridView冲突
- Android 解决 ScrollView嵌套ListView、GridView冲突显示不全的最快实现
- scrollview嵌套listview,gridview 显示不全万能解决办法
- ScrollView嵌套GridView、ListView的解决办法
- 解决ScrollView 嵌套 ListView GridView显示不全,以及默认不在ScrollView顶部的问题
- ScrollView中嵌套ListView或GridView,只显示一行
- 解决ScrollView下嵌套ListView、GridView显示不全的问题(冲突)
- ListView,GridView与ScrollView嵌套使用的故事
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- Android-scrollview嵌套listview、webview、gridview不置顶问题
- android 在一个scrollView里面嵌套一个需要滑动的控件(listView、gridView)
- android ScrollView中嵌套GridView,ListView只显示一行的解决办法
- ScrollView下嵌套GridView或ListView默认不在顶部的解决方法
- 解决ScrollView下嵌套ListView、GridView显示不全的问题
- 解决ScrollView下嵌套ListView、GridView显示不全的问题
- Android学习之——ScrollView和ListView,GridView嵌套
- [android] ScrollView 嵌套 ListView GridView问题
- ScrollView中嵌套GridView,ListView只显示一行的解决办法
- 解决ScrollView中嵌套ListView或GridView导致的ScrollView自动滚动到ListView或GridView位置的问题
- ScrollView 和 ListView ,GridView的嵌套问题