前两天测试组反馈一个bug,列表(实质上是一个ListView)在OPPO R6手机上无法显示底部:ListView可以滑动,但是底部的选项框无法显示。
ListView相信很多人都使用过,甚至有些小伙伴都已经开始使用RecyclerView了,它经常用来做列表。基本用法如下:
ListView listView = findViewById(resId);
BaseAdapter adapter = new MyBaseAdapter(Context, Arraylist);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
但是如果需要在顶部/底部展示一个不同于其他item的view该怎么办呢?两种办法:
ListView listView = findViewById(resId);
BaseAdapter adapter = new MyBaseAdapter(Context, Arraylist);
listView.setAdapter(adapter);
View headView = (View) LayoutInflater.from(this).inflate(R.layout.headview, null);
View footView = (View) LayoutInflater.from(this).inflate(R.layout.footview, null);
listView.addHeadView(headView);
listView.addFootView(footView);
adapter.notifyDataSetChanged();
结果,我们的项目在OPPO R6手机上超出了一屏,只能滑动显示到最后一个normal item,却无法查看到底部的footView,其他手机上正常显示。Why???
纠结了一下,将以上方法二的代码修改如下:
ListView listView = findViewById(resId);
BaseAdapter adapter = new MyBaseAdapter(Context, Arraylist);
View headView = (View) LayoutInflater.from(this).inflate(R.layout.headview, null);
View footView = (View) LayoutInflater.from(this).inflate(R.layout.footview, null);
listView.addHeadView(headView);
listView.addFootView(footView);
listView.setAdapter(adapter);// 将设置适配器的操作延后
adapter.notifyDataSetChanged();
一行代码的改动,OPPO R6上FootView神奇的显示出来了!!!
请看ListView.setAdapter(adapter)部分源码:
...
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {// 如果headView的集合,或者footView的集合不为空,就进行Adapter转换
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;// 没有执行添加头部和尾部的操作
}
...
请看ListView.addFootView(footView)部分源码;
...
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {// 执行过了setAdapter(adapter)
if (!(mAdapter instanceof HeaderViewListAdapter)) {// 如果Adapter没进行过转换,就转换
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
...
}
由以上源码可以看出,无论是先添加FootView还是先setAdapter,mAdapter都会被转换成HeaderViewListAdapter,其中HeaderViewListAdapter和BaseAdapter一样,都是ListAdapter的实现类,是对BaseAdapter的二次封装。
所以我推断,有可能是在OPPO的framework源码中,ListView.addFootView(footview)方法中,有可能是这样的:
...
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {// 执行过了setAdapter(adapter)
if (!(mAdapter instanceof HeaderViewListAdapter)) {// 如果Adapter没进行过转换,就转换
// mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);// 这行代码被人无意中注释或删除了
}
...
}
不知道是否猜测正确,仅供参考。
所以,解决ListView的底部在OPPO等手机上无法显示的办法就是,将setAdaper(adapter)操作放在addFootView(footview)之后进行。希望对大家有所帮助。
查看原文:http://blog.xiongit.com/2015/12/androidlistview%e5%ba%95%e9%83%a8footview%e6%97%a0%e6%b3%95%e6%98%be%e7%a4%ba%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3/