安卓控件 listView 的学习及优化 (ConvetView、viewHolder)

一. listView 的学习

众所周知ListView 是一个控件,一个在垂直滚动的列表中显示条目的一个控件。


使用方法为:

1. 布局添加Listview
2. 在对应的activity找到listview
3. 创建一个Adapter适配器继承BaseAdapter,封装4个方法(如下图)

getcount: 返回listview显示的条目总数。
getItem : 返回当前点击listview的条目。
getItemId : 返回点击条目对应在listview中的位置。
getview:告诉listview每个条目显示的内容。

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>        @Override
        public int getCount() {
            return 0;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
        }</code></span></span>
  • 1

4. 创建Adapter的一个对象,设置给listview。
listview.setAdapter(ListAdapter adapter);


二. listView 的优化

1.初步优化

依次封装以上4个方法,其中最重点的是 getview方法,主要的优化也是在其中。

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>    public View getView(int position, View convertView, ViewGroup parent) 
    {
            return null;
    }</code></span></span>
  • 1

注意观察getView方法中的参数,position为点击条目的具体位置,重点是 convertView ,一个listview中会有许多条目,而一个条目中可能由几个小控件(例如TextView、Button)组成,而 convertView指的是一个单独条目(View对象),它包括了那几个小控件。

为了让listview呈现出条目,在getView方法中我们需要不停的重新声明view对象,将layout布局inflate转换成view后,用findViewById获取一个条目中的具体控件进行赋值操作,如果需要大量条目展示,无疑这会消耗内存。

复用convertView : getview方法会传进来一个convertView,convertView是指曾经使用过的view对象,可以被重复使用,但是在使用前需要判断是否为空,不为空直接复用,并作为getview方法的返回对象。(如上图)

所以我们的第一步优化就是复用convertView(如下图所示)

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;
    if(convertView != null){//判断converView是否为空,不为空重新使用
        view = (TextView) convertView;
    }else{
        view = new TextView(mContext);//创建一个textView对象
        }
    return view;
}</code></span></span>
  • 1

再进行 if 判断之后,即复用完convertView对象后,再用findViewById获取小控件进行展示操作。

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>    //2.获取view上的子控件对象
    TextView item_tv_title= (TextView) view.findViewById(R.id.item_tv_title);
    //3.获取postion位置条目对应的list集合中的新闻数据,Bean对象
    NewsBean newsBean = list.get(position);
    //4.将数据设置给这些子控件做显示
    item_tv_title.setText(newsBean.title);
</code></span></span>
  • 1

这样看起来解决了问题,其实不然!如果现在需要展示100条 条目,虽然复用了对象,但是这意味着 findViewById的操作要重复100次,你的可用内存会慢慢减少,最后手机程序崩溃!(如下图)




2.完全优化


优化重点:

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>(1):复用convertView
(2):复用ViewHolder让其减少findViewById()次数
(3):static ViewHolder
(4):分页算法</code></span></span>
  • 1

如上所说,不要去一味的 findViewByID(),它是一个耗时的操作,需要优化,使用viewHolder类,它把每一个条目View放在Holder中,当getView方法第一次创建convertView对象时,会把这些条目view找出来。然后用convertView的setTag将viewHolder设置到Tag中,这样下次呈现ListView时会直接从Tag中取出。当第二次复用convertView时,只需从convertView中getTag取出即可。(代码如下)

<span style="color:#333333"><span style="background-color:#f5f5f5"><code>public View getView(int position, View convertView, ViewGroup parent) {
    //1,复用convertView 
            //复用viewHolder步骤一
            ViewHolder holder = null;
            if(convertView == null){
                convertView = View.inflate(getApplicationContext(), R.layout.listview_item, null);
                //2,减少findViewById()次数
                //复用viewHolder步骤三
                holder = new ViewHolder();
                //复用viewHolder步骤四
viewHolder.text1 = convertView.findViewById(R.id.text1);
                //复用viewHolder步骤五
                convertView.setTag(holder);
            }else{
                holder = (ViewHolder) convertView.getTag();
                 }
            viewHolder.text1.setText("文本内容");
}

//复用viewHolder步骤二
    static class ViewHolder{
        TextView text1;
    }</code></span></span>
  • 1

以上代码解析:

(1) convertView为空,代表当前条目是首次构建,就需要inflate转换布局,用findViewByID查找小控件,这是为了后面的条目去进行复用。

(2)创建一个ViewHolder对象,去存储第一次找到的所有的小控件。当前的viewHolder对象,又由convertView去做存储。 setTag(viewHolder)

(3)复用convertView的条目展示的时候,找到之前设置过的tag . ViewHolder viewHolder = getTag()viewHolder中就包含第一次构建时findViewById找过的小控件。


以上即为 listView控件的优化过程,至于分页涉及到 数据库分页查询,暂时不写。关于优化的讲解,其实直接讲第二点(完全优化)即可,但是我想循序渐进,因为初学者的我刚开始用listView使用得都是(初步优化),渐渐的才发现listView需要更彻底的优化,想让大家体会一点点深入的过程。希望对大家有所帮助 :)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春哥111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值