ListView 緩存

ListView:ListView是一個能夠?qū)?shù)據(jù)集合以動態(tài)滾動的方式展示到用戶界面上的View梦染。

1. ListView的適配器模式

適配器模式.png

說明:ListView的適配器模式將數(shù)據(jù)資源和視圖分離,通過適配器來連接兩者灯谣,屬于MVC模式。

2. ListView的垃圾回收機制RecycleBin

RecycleBin機制.png

說明:適配器的getCount()方法用來計算數(shù)據(jù)資源的長度卷胯,有n條數(shù)據(jù)就會調(diào)用n次getView()方法來繪制Item摊趾,當(dāng)數(shù)據(jù)長度很多時,ListView的recycleBin機制(內(nèi)存回收機制)保證滑動時不會發(fā)生OOM(內(nèi)存泄漏)藤肢。
如:一旦Item0劃出屏幕,則Item0就會被放到RecycleBin機制里糯景,在Item6要顯示的時候再從緩存中獲取到緩存的Item0治拿,達到復(fù)用的目的暇榴。recycleBin機制保證了僅界面內(nèi)顯示的數(shù)據(jù)會存儲在內(nèi)存止吐,故列表滑動時不會造成內(nèi)存泄漏超凳。

3. ListView的優(yōu)化

(1) convertView復(fù)用和viewHolder

//繪制ListView的每個Item
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null){
                viewHolder = new ViewHolder();
                convertView = LayoutInflater.from(ListViewTestActivity.this).inflate(R.layout.item_listview,null);
                viewHolder.title = convertView.findViewById(R.id.title);
                viewHolder.content= convertView.findViewById(R.id.content);
                convertView.setTag(viewHolder);
            }else {
                viewHolder = (ViewHolder)convertView.getTag();
            }
            viewHolder.title.setText("標題");
            viewHolder.info.setText("內(nèi)容");
            return convertView;
        }

        class ViewHolder{
            private TextView title;
            private TextView content;
        }

convertView是ListView優(yōu)化最重要的一點:convertView其實是緩存的作用。利用緩存convertView來做判斷怠惶,當(dāng)緩存中convertView為空時才創(chuàng)建相應(yīng)的View涨缚,存在則調(diào)用已有的View,從而提升了性能策治。
自定義viewHolder:View是一個二叉樹的結(jié)構(gòu)脓魏,每次遍歷都很耗時,利用viewHolder可以減少每次findViewById()的調(diào)用次數(shù)通惫,從而在時間上進行優(yōu)化茂翔。
(2) 三級緩存和監(jiān)聽滑動事件
三級緩存:圖片加載時需要用到緩存機制來進行。
監(jiān)聽滑動事件:盡量不要在getView()中做耗時操作履腋,保證ListView滑動的流暢性珊燎,避免滑動時卡頓。如果一定要在ListView滑動時加載,可以設(shè)置ListView的監(jiān)聽事件俐末,當(dāng)滑動停止時再去加載整個圖片。
(3) 其他

  • ListView的Item布局中盡量避免半透明的元素:半透明的繪制比不透明更耗時
  • 可以開啟硬件加速

4. ListView使用

(1) ListViewTestActivity.java

package comi.example.liy.mytestdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by liy on 2019-11-08 15:38
 */
public class ListViewTestActivity extends AppCompatActivity {

    private ListView listView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);
        listView = findViewById(R.id.listview);
        listView.setAdapter(new MyAdapter(this));
    }

    class MyAdapter extends BaseAdapter{
        private Context context;
        private ArrayList<NewsInfo> newsInfos = new ArrayList<>();

        public MyAdapter(Context context) {
            this.context = context;
            newsInfos = new NewsInfo().getNewsInfos();
        }

        //計算數(shù)據(jù)資源的長度:有n條數(shù)據(jù)就會調(diào)用n次getView()方法來繪制Item奄侠,當(dāng)數(shù)據(jù)長度很多時卓箫,ListView的recycleBin機制(內(nèi)存回收機制)保證滑動時不會發(fā)生OOM(內(nèi)存泄漏)
        @Override
        public int getCount() {
            if (newsInfos == null){
                return 0;
            }
            return newsInfos.size();
        }

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

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

        //繪制ListView的每個Item
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null){
                convertView = LayoutInflater.from(ListViewTestActivity.this).inflate(R.layout.item_listview,null);
                viewHolder = new ViewHolder();
                viewHolder.title = convertView.findViewById(R.id.title);
                viewHolder.content = convertView.findViewById(R.id.content);
                convertView.setTag(viewHolder);
            }else {
                viewHolder = (ViewHolder)convertView.getTag();
            }
            viewHolder.title.setText(newsInfos.get(position).getTitle());
            viewHolder.content.setText(newsInfos.get(position).getContent());
            return convertView;
        }

        class ViewHolder{
            private TextView title;
            private TextView content;
        }
    }

}

(2) NewsInfo.java

package comi.example.liy.mytestdemo;

import java.util.ArrayList;

/**
 * Created by liy on 2019-11-08 15:54
 */
public class NewsInfo {
    private String title;
    private String content;

    public NewsInfo() {

    }

    public NewsInfo(String title, String content) {
        this.title = title;
        this.content= content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    //創(chuàng)建測試數(shù)據(jù)
    public ArrayList<NewsInfo> getNewsInfos(){
        ArrayList<NewsInfo> newsInfos = new ArrayList<>();
        newsInfos.add(new NewsInfo("標題1","信息內(nèi)容1"));
        newsInfos.add(new NewsInfo("標題2","信息內(nèi)容2"));
        newsInfos.add(new NewsInfo("標題3","信息內(nèi)容3"));
        newsInfos.add(new NewsInfo("標題4","信息內(nèi)容4"));
        newsInfos.add(new NewsInfo("標題5","信息內(nèi)容5"));
        newsInfos.add(new NewsInfo("標題6","信息內(nèi)容6"));
        newsInfos.add(new NewsInfo("標題7","信息內(nèi)容7"));
        newsInfos.add(new NewsInfo("標題8","信息內(nèi)容8"));
        newsInfos.add(new NewsInfo("標題9","信息內(nèi)容9"));
        newsInfos.add(new NewsInfo("標題10","信息內(nèi)容10"));
        return newsInfos;
    }

}

(3) activity_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</LinearLayout>

(4) item_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/title"
            android:textSize="20sp"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/content"
            android:textSize="16sp"/>
    </android.support.v7.widget.LinearLayoutCompat>
</LinearLayout>

(5) 運行效果


運行效果.png

拓展實現(xiàn)ListView的橫向滑動可置頂或刪除列表項

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垄潮,一起剝皮案震驚了整個濱河市烹卒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弯洗,老刑警劉巖旅急,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異牡整,居然都是意外死亡藐吮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門逃贝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谣辞,“玉大人,你說我怎么就攤上這事沐扳∧啻樱” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵沪摄,是天一觀的道長躯嫉。 經(jīng)常有香客問我,道長杨拐,這世上最難降的妖魔是什么祈餐? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮戏阅,結(jié)果婚禮上昼弟,老公的妹妹穿的比我還像新娘。我一直安慰自己奕筐,他們只是感情好舱痘,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著离赫,像睡著了一般芭逝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渊胸,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天旬盯,我揣著相機與錄音,去河邊找鬼。 笑死胖翰,一個胖子當(dāng)著我的面吹牛接剩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播萨咳,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼懊缺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了培他?” 一聲冷哼從身側(cè)響起鹃两,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舀凛,沒想到半個月后俊扳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡猛遍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年馋记,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懊烤。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡抗果,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奸晴,到底是詐尸還是另有隱情冤馏,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布寄啼,位于F島的核電站逮光,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏墩划。R本人自食惡果不足惜涕刚,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乙帮。 院中可真熱鬧杜漠,春花似錦、人聲如沸察净。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氢卡。三九已至锈至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間译秦,已是汗流浹背峡捡。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工击碗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人们拙。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓稍途,卻偏偏與公主長得像,于是被迫代替她去往敵國和親砚婆。 傳聞我的和親對象是個殘疾皇子晰房,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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