当我们在使用Listview这类的控件和scrollview嵌套使用的时候会调用一个动态计算listview高度的方法。网上大部分方法基本都如下:
- public class Utils {
- public static void setListViewHeightBasedOnChildren(ListView listView) {
- ListAdapter listAdapter = listView.getAdapter();
- if (listAdapter == null) {
-
- return;
- }
-
- int totalHeight = 0;
- for (int i = 0; i < listAdapter.getCount(); i++) {
- View listItem = listAdapter.getView(i, null, listView);
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }
-
- ViewGroup.LayoutParams params = listView.getLayoutParams();
- params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
- listView.setLayoutParams(params);
- }
- }
但是有时候我们会发现每次调用的时候都会产生在listItem.measure(0,0)报空指针异常。但是你去debug会发现listItem 并不是为空,那么为啥会报错呢。你去看你的item的布局会发现肯定不是LinearLayout,这个时候把它换为LinearLayout 就好了。网上的说法是原来是 Linearlayout重写了onmeasure方法,其他的布局文件没有重写onmeasure,所以在调用listItem.measure(0, 0); 会报空指针异常,如果想用这个东东,就必须用linearlayout布局。但是我看源码发现其实并不能这样说,其他布局也是重写了onmeasure方法的,不过谷歌有特别备注说明:
大伙去翻译翻译看看啥意思。而且这种情况并不是在所有的手机上会出现,现在很多手机厂商有修改rom。我只是在华为的一款手机上报了这个错。基于这些我写了一个稳妥一点的计算方法:
- public class Utils {
- public static void setListViewHeightBasedOnChildren(ListView listView) {
-
- ListAdapter listAdapter = listView.getRefreshableView().getAdapter();
- if (listAdapter == null) {
- return;
- }
-
- int totalHeight = 0;
-
- for (int i = 0; i < listAdapter.getCount(); i++) {
-
- View listItem = listAdapter.getView(i, null, listView);
- if (listItem == null) continue;
-
- if (listItem instanceof LinearLayout){
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }else {
- try {
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }catch (NullPointerException e){
- totalHeight += DeviceUtil.dp_to_px(ClientApplication.instance,80);
- LogOut.e("bobge","NullPointerException");
- }
- }
-
- totalHeight += listItem.getMeasuredHeight();
-
- }
-
- ViewGroup.LayoutParams params = listView.getLayoutParams();
-
- params.height = totalHeight
- + (listView.getRefreshableView().getDividerHeight() * (listAdapter.getCount() - 1));
-
-
- listView.setLayoutParams(params);
-
- }
- }