ScrollView中放置ListView
来源:互联网 发布:js正则手机号码验证 编辑:程序博客网 时间:2024/04/29 04:26
最近有个需求是需要在ScrollView中放置一个ListView,如果不做处理的话,直接放置控件会导致:
- ListView的高度设置为wrap_content时,每个item的高度无法控制,可能导致item高度为0而不显示。
- ListView的高度设置为wrap_content时,疯狂调用getView方法导致卡顿。
- ListView的高度设置了合适的高度后,ListView无法滑动。
其对应的解决方法:
在ListView调用了
setAdapter
或者notifyDataChange
后,使用该方法重新设置ListView的高度。public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) return; int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED); int totalHeight = 0; View view = null; for (int i = 0; i < listAdapter.getCount(); i++) { //获取每个item的view view = listAdapter.getView(i, view, listView); if (i == 0) view.setLayoutParams(new AbsListView.LayoutParams(desiredWidth, AbsListView.LayoutParams.WRAP_CONTENT)); view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED); //计算总高度 totalHeight += view.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); //加上divider的高度 params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); listView.requestLayout();}
该方法原理就是通过adapter的getView方法返回item的view,计算每个item的高度height乘以item的个数,最后加上divider的高度。(如果知道每个item的高度,可以直接获取adapter的count乘以高度即可,省区调用getView方法的时间)
使用该方法需要注意:1. item的根布局是必须是LinearLayout等重写了`onMeasure`方法的layout,因为获取高度时用到了`view.getMeasuredHeight()`方法.2. 该方法会在Adapter的getView方法前被调用。
在ListView外部放置一层单独的FrameLayout(性能最高),设置Layout的高度为wrap_content,然后设置ListView的高度为fill_parent,最后在
setAdapter
或notifyDataChange
后修改setListViewHeightBasedOnChildren
方法,通过该方法返回带有正确高度的LinearLayout.LayoutParams(你没有看错,用LinearLayout.LayoutParams来设置FrameLayout),以此来设置FrameLayout的高度。这样不会疯狂调用getView方法了。在onTouch事件中取消父布局的touch劫持。
listView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.getParent().requestDisallowInterceptTouchEvent(true); return false; }});
如果使用了Github开源项目-PullToRefreshListView,它有一个headView和一个BottomView,所以它计算高度的方法会不同:
public static void setListViewHeightBasedOnChildren(PullToRefreshListView listView) { ListAdapter listAdapter = listView.getRefreshableView().getAdapter(); if (listAdapter == null) return; int totalHeight = 0; View view = null; //去掉头尾两个view for (int i = 1; i < listAdapter.getCount()-1; i++) { view = listAdapter.getView(i, view, listView); totalHeight += view.getLayoutParams().height; } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getRefreshableView().getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); listView.requestLayout();}
这里使用的是LayoutParams的height作为item的高度,所以在adapter的getView方法中,应该这样初始化:
public View getView(int position, View convertView, ViewGroup parent) { convertView = inflater.inflate(R.layout.parenting_listview_item,parent,false);}
- ScrollView中放置ListView
- scrollview,里面放置listview时候高度显示不全
- ScrollView中包含ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中添加ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套listview
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中添加listView
- ScrollView中嵌套ListView
- 1027. 打印沙漏(20)
- 1007. Maximum Subsequence Sum (25)
- Winedt "系统找不到指定文件" 解决办法
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 创建第一个Django工程之视图和URL配置,404错误
- ScrollView中放置ListView
- faster-rcnn的记录
- 使用Akka的Actor和Future简单地实现并发处理
- leetcode:Union Find:Surrounded Regions(130)
- 电商网站快速排名的独家秘籍
- 异步加载-AsyncTask
- 欢迎使用CSDN-markdown编辑器
- 牛顿迭代法(Newton's Method)
- android开发之增加永不暗屏菜单