Android:ListView底部footview无法显示问题解决

来源:互联网 发布:qt geant4 混合编程 编辑:程序博客网 时间:2024/05/21 15:40

前两天测试组反馈一个bug,列表(实质上是一个ListView)在OPPO R6手机上无法显示底部:ListView可以滑动,但是底部的选项框无法显示。

ListView用法科普

ListView相信很多人都使用过,甚至有些小伙伴都已经开始使用RecyclerView了,它经常用来做列表。基本用法如下:

ListView listView = findViewById(resId);BaseAdapter adapter = new MyBaseAdapter(Context, Arraylist);listView.setAdapter(adapter);adapter.notifyDataSetChanged();

但是如果需要在顶部/底部展示一个不同于其他item的view该怎么办呢?两种办法:

  • 方法一:复写BaseAdapter的getItemViewType(int position);getViewTypeCount()两个方法,不具体展开,与本文无关。
  • 方法二:使用ListView.addHeadView(headView),ListView.addFootView(footView)。用法如下:
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();

Demo效果如下图:
xiongit博客listview.addFootView(footview)

结果,我们的项目在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/

1 1
原创粉丝点击