自定義BaseAdapter完美解決ListView異常:java.lang.IllegalStateException

在我們Android 開發(fā)中低散,ListView是在常用不過的控件了婆瓜。但是有時(shí)候會(huì)爆出這種異常苔严,就搞得好尷尬了每瞒。


異常圖片

明明我們?cè)诖a中的確是有調(diào)用adaptor.notifyDataSetChanged()這個(gè)方法的,明顯沒問題啊暇唾。
后來我查代碼促脉,才發(fā)現(xiàn),在我們更新過程中大部分使用到的是異步操作策州,但是如果網(wǎng)絡(luò)很卡瘸味,然后又發(fā)出了大量的請(qǐng)求的話,那么就會(huì)出現(xiàn)這個(gè)問題够挂。要怎么解決這個(gè)問題呢旁仿?

這是代碼

import java.util.ArrayList;
import java.util.List;

import android.util.SparseArray; 
import android.view.View;
import android.view.ViewGroup;

/**
 * @author 肖蕾
 * @param <DataType>
 *            傳入的數(shù)據(jù)類型
 * @param <viewHolder>
 *            ViewHoler的類型
 */
public abstract class BaseAdapter<DataType, viewHolder extends BaseAdapter.Holder> extends android.widget.BaseAdapter
{
    /**
     * 保存的數(shù)據(jù)
     */
    private List<DataType> list = new ArrayList<DataType>();
    private List<DataType> outer_list;

    public BaseAdapter(List<DataType> list)
    {
        this.outer_list = list;
        this.list.addAll(outer_list);
    }

    @Override
    public int getCount()
    {
        return getItemCount();
    }

    @Override
    public DataType getItem(int position)
    {
        return list.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }
    
    @Override
    public void notifyDataSetChanged()
    {
        this.list.clear();
        this.list.addAll(outer_list);
        super.notifyDataSetChanged();
    }
    
    /**
     * View 的創(chuàng)建
     * 
     * @param parent
     *            父控件
     * @param viewType
     *            類型
     * @return
     */
    public abstract viewHolder onCreateViewHolder(ViewGroup parent, int viewType);

    /**
     * ViewHolder與數(shù)據(jù)的綁定
     * 
     * @param holder
     *            viewHoler對(duì)象
     * @param data
     *            數(shù)據(jù)
     * @param position
     *            定位
     */
    public abstract void onBindViewHolder(viewHolder holder, DataType data, int position);

    public int getItemCount()
    {
        if (list == null)
        {
            return 0;
        }
        return list.size();
    }

    public int getItemViewType(DataType data, int position)
    {
        return super.getItemViewType(position);
    }

    @SuppressWarnings("unchecked")
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        viewHolder holder = null;
        DataType data = list.get(position);
        if (convertView == null)
        {
            holder = onCreateViewHolder(parent, getItemViewType(data, position));
            convertView = holder.getRootView();
        } else
        {
            holder = (viewHolder) convertView.getTag();
        }
        onBindViewHolder(holder, data, position);
        return convertView;
    }

    public static class Holder
    {
        private View root;
        private SparseArray<View> store = new SparseArray<View>();
        
        @SuppressWarnings("unchecked")
        public <T extends View> T get(int id) 
        {
            View result = store.get(id);
            if(result == null)
            {
                result = root.findViewById(id);
                store.append(id, result);
            }
            return (T) result;
        }

        public Holder(View view)
        {
            this.root = view;
        }

        public View getRootView()
        {
            root.setTag(this);
            return root;
        }
    }
}

使用方法

public class mAdapter extends BaseAdaptor<String, BaseAdaptor.Holder>
{
    public mAdapter(List<String> list)
    {
        super(list);
    }
    /**
    * 新建一個(gè)ViewHoler
    */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = View.inflate(parent.getContext(), R.layout.item, null);
        Holder holder = new Holder(view);
        return holder;
    }
    /**
    * ViewHoler與數(shù)據(jù)綁定
    */
    @Override
    public void onBindViewHolder(Holder holder, String data, int position)
    {
        TextView text = holder.get(R.id.text);
        text.setText(data);
    }
}

原理

原理是什么呢?我們?cè)赼daptor內(nèi)部就封裝了一個(gè)List用于保存用戶傳過來的List數(shù)據(jù)孽糖,我們這里只是對(duì)外部的list有一個(gè)引用枯冈,但是真正使用到的list,卻是內(nèi)部的List,通過每一次調(diào)用notifyDataSetChanged()方法办悟,則自動(dòng)將內(nèi)部的list數(shù)據(jù)與外部的list數(shù)據(jù)同步一次尘奏。再調(diào)用父類的更新、這樣病蛉,我們玩來玩去就是外部的list炫加,并不會(huì)對(duì)內(nèi)部listview使用到的list有任何影響瑰煎。就完美屏蔽了這個(gè)異常了。

另外

分享一句我最喜歡的歌詞:
如果那兩個(gè)字沒有顫抖
我不會(huì)發(fā)現(xiàn)我難受
怎么說出口也不會(huì)是分手

如果對(duì)于明天沒有要求
牽牽手就像旅游(女友)
成千上萬(wàn)個(gè)門口
總有一個(gè)人要先走

懷抱既然不能逗留
何不在離開的時(shí)候
一邊享受一邊淚流

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俗孝,一起剝皮案震驚了整個(gè)濱河市酒甸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赋铝,老刑警劉巖插勤,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異柬甥,居然都是意外死亡饮六,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門苛蒲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卤橄,“玉大人,你說我怎么就攤上這事臂外】咂耍” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵漏健,是天一觀的道長(zhǎng)嚎货。 經(jīng)常有香客問我,道長(zhǎng)蔫浆,這世上最難降的妖魔是什么殖属? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮瓦盛,結(jié)果婚禮上洗显,老公的妹妹穿的比我還像新娘。我一直安慰自己原环,他們只是感情好挠唆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘱吗,像睡著了一般玄组。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谒麦,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天俄讹,我揣著相機(jī)與錄音,去河邊找鬼弄匕。 笑死颅悉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迁匠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼城丧!你這毒婦竟也來了延曙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤亡哄,失蹤者是張志新(化名)和其女友劉穎枝缔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚊惯,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡愿卸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了截型。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趴荸。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宦焦,靈堂內(nèi)的尸體忽然破棺而出发钝,到底是詐尸還是另有隱情,我是刑警寧澤波闹,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布酝豪,位于F島的核電站,受9級(jí)特大地震影響精堕,放射性物質(zhì)發(fā)生泄漏孵淘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一歹篓、第九天 我趴在偏房一處隱蔽的房頂上張望瘫证。 院中可真熱鬧,春花似錦滋捶、人聲如沸痛悯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)载萌。三九已至,卻和暖如春巡扇,著一層夾襖步出監(jiān)牢的瞬間扭仁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工厅翔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乖坠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓刀闷,卻偏偏與公主長(zhǎng)得像熊泵,于是被迫代替她去往敵國(guó)和親仰迁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評(píng)論 25 707
  • 簡(jiǎn)介 在Android開發(fā)中ListView是比較常用的組件顽分。 以列表的形式展示具體內(nèi)容徐许。 并且能夠根據(jù)數(shù)據(jù)的長(zhǎng)度...
    上善若水Ryder閱讀 6,969評(píng)論 2 5
  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法卒蘸,并非Fa...
    孫小磊閱讀 1,963評(píng)論 0 3
  • 我叫魏大勇雌隅,在河南的少林寺待了十年了,今天因?yàn)樵谒峦獯蟠虺鍪侄`犯寺規(guī)缸沃,被主持?jǐn)f出山門恰起。 但我知道,打的是日本人趾牧,...
    安諳閱讀 736評(píng)論 3 0
  • 至尊寶想救紫霞检盼,必須要打敗牛魔王;要打敗牛魔王武氓,必須變成孫悟空梯皿;要變成孫悟空,必須忘掉七情六欲县恕,從此與紫霞是陌路...
    陌上輕風(fēng)閱讀 163評(píng)論 0 0