Android app--listviewのいくつかの使い方(多重化、非多重化、半多重化)についてitem状態の変化の問題を解決する

17750 ワード

1.最も基本的な非多重化から、すなわち、AdapterのgetViewメソッドではViewHolderは使用されない.
このようにして、つまりlistViewを上下にスライドさせ、隠されたアイテムがスライドされているときに、毎回このアイテムを再描画するとメモリが消費され、itemのデータ量が大きいとスライドカートンの現象が発生する可能性が高い.明らかにカートンは開発者が最も見たくないので、このような使い方はpassにほとんど落ちています.
2.各項目を多重化します.つまり、ViewHolderをAdapterのgetViewに追加します.コードを具体的に見る
package com.tdotapp.rd.adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.tdotapp.rd.R;

import java.util.List;

/**
 * Created by GT on 2015/11/16.
 */
public class typeAdapter extends BaseAdapter {
    //   
    private Context mContext;
    //item      
    private List listBeans;
    //    
    public typeAdapter(Context context, List listBeans) {
        this.mContext = context;
        this.listBeans = listBeans;
    }

    @Override
    public int getCount() {
        return listBeans.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //ViewHolder
        ViewHolder viewHolder=null;
        //           convertView    ,   , else     ,  ,     item  
        if (convertView == null) {
            //new ViewHolder ,       
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.type_spinner_item, null);
            viewHolder.tvfabuwz = (TextView) convertView.findViewById(R.id.tvfabuwz);
            //  convertView setTag  , viewHolder    ,      
            convertView.setTag(viewHolder);
        } else {
            //       item  
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.tvfabuwz.setText(listBeans.get(position));
        return convertView;
    }

    class ViewHolder {
        TextView tvfabuwz;

    }
}

コードには詳細なコメントが追加されており、多重化は絶対にlistViewの最適化案であり、毎回新しいitem項目を描く必要はなく、一度作成してからインタフェースを多重化することで、いくら多くの項目でもメモリを消費する必要はありません.原理はスライドとスライドに相当し、インタフェースは元のもので、データを交換しただけです.
多重化には多重化のメリットがあり、もちろんデメリットもあります.多重化を使用する場合、各項目にデータが表示されているだけであれば、多重化は絶対に使いやすいです.ただしlistViewの各項目が操作可能であれば(例えばeditTextがあって、入力内容があって、上下にスライドした後、入力ボックスの中の内容が変更されるかどうかを見たり、下に多重化された時にこの入力ボックスの中の内容が現れたりします.例えば、ラジオボックスがあって、この項目が選択された後、上下にスライドした後、この選択状態が暴走したかどうかを見て、前の選択状態が消えたかどうかを見ます....などなど、itemアイテムの状態に関係するものは、多重化時に問題が発生するに違いありません)
どうやって解決するのか、この時あなたが考えているのはきっと多重化しないでしょう.多重化しないと状態が変わることはありませんが、多重化しないと、しばらくスライドするかもしれません.あなたのこのlistViewはitemインタフェースを再描画し続けるためにメモリが消費されすぎて、スライドしない場合があります.
次に、スライド後にitem項目が変更された状態がまだあることを保証し、itemを再描画しすぎてメモリ消費が大きくならないことを保証する方法について説明します.
この方法はxiaanming大牛のブログから出ています(少し変更します)
public class NewsAdapter extends BaseAdapter {

    //   Context
    private Context mContext;
    List list = new ArrayList<>();
    //  hashMap             item
    HashMap, View> lmap = new HashMap, View>();
    private ImageLoader imageLoader = ImageLoader.getInstance();
    public NewsAdapter(Context context, List listViewList) {
        this.mContext = context;
        this.list = listViewList;

    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder ViewHolder;
        //          item ,       ,     ,       
        if (lmap.get(position) == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.news_item, null);
            ViewHolder = new ViewHolder(convertView);
            convertView.setTag(ViewHolder);
            lmap.put(position,convertView);
        } else {
            convertView = lmap.get(position);
            ViewHolder = (ViewHolder) convertView.getTag();
        }
    ViewHolder.tv_newstime.setText(list.get(position).getDate());
    ViewHolder.tvnewsneirong.setText(list.get(position).getContent());
    ViewHolder.tvnewstitle.setText(list.get(position).getTitle());
    imageLoader.displayImage(list.get(position).getImg(), ViewHolder.imgnewspic, Tools.setBeforImageoption());
    return convertView;
}

//  viewHolder
class ViewHolder {
    TextView tvnewstitle,newstype,tvnewsneirong,tv_newstime;
    ImageView imgnewspic;

    public ViewHolder(View convertView) {
        tvnewstitle = (TextView) convertView.findViewById(R.id.tvnewtitle);
        imgnewspic = (ImageView) convertView.findViewById(R.id.imgnewspic);
        newstype= (TextView) convertView.findViewById(R.id.newstype);
        tvnewsneirong= (TextView) convertView.findViewById(R.id.tvnewsneirong);
        tv_newstime= (TextView) convertView.findViewById(R.id.tv_newstime);
    }
}

原理は、新しいインタフェースがあって、再描画して、すでに存在するインタフェースは直接出します.これにより,毎回新しいitemアイテムがインタフェースを再描画され,再描画されたインタフェースを集合に入れて保存され,itemアイテムの状態が服用によって変化する問題を効果的に防止できる.
しかし、これで多重化は大幅に割引されます.メモリ消費も向上します.
夏大のブログの返信を見ると、大神さんは状態もtagに入れて保存し、同じように多重化を実現する際に状態を多重化できると話しています.
不明な点があれば、回答していただき、開発者の皆様と共同で検討できて光栄です.
転載先:
http://blog.csdn.net/qq_33078541?viewmode=contents