Android RecyclerView的卡頓問題

本文其實是上一篇Android本地app操作相關基礎的延伸秃励,然而內容基本沒什么聯(lián)系了(初學者身份瞬間暴露劝堪,打一槍換一個地方←_←)晚岭,就不好意思再添個“續(xù)”或者“(2)”了~~
照舊先碼字嗤无!

RecyclerView為什么會卡

RecyclerView作為v7包的新控件壶愤,自從推出就廣受Android Developer們歡迎,實際上它已經取代了ListView和GridView兩位老前輩的地位乔夯。然而不少親們想必也已經發(fā)現(xiàn)了:沒有優(yōu)化過的Recycler性能很poor期虾。上一篇博主使用的item也僅僅是一個圖兩串字而已,結果一滑動就卡的要命驯嘱,不能忍!
那么why喳坠?回想在用ListView和GridView的adapter時鞠评,我們是用一種叫ViewHolder的自定義類(容器)來實現(xiàn)優(yōu)化的,而RecyclerView的特性之一就是強制你使用它的RecyclerView.ViewHolder壕鹉√昊希可是,RecyclerView.ViewHolder要比我們寫的那個單純的容器復雜多了(源碼里算上注釋有大約500行)晾浴,與RecyclerView.Adapter的聯(lián)系也是千絲萬縷负乡。


按stackoverflow上面比較通俗的解釋:RecyclerView.Adapter里面的onCreateViewHolder()方法和onBindViewHolder()方法對時間都非常敏感。類似I/O讀寫脊凰,Bitmap解碼一類的耗時操作抖棘,最好不要在它們里面進行。


如何解決這個問題

  • 首先當然得優(yōu)化你的item狸涌,合理運用<include>切省,<merge>,<ViewStub>等標簽帕胆,使布局層次盡量少——其實ListView和GridView里你也應該這么做朝捆,應該當成是一種寫UI的習慣。
  • 其次就是靈活使用各種第三方庫懒豹,去完成各種耗時操作芙盘,比如通過Glide或者是Picasso加載圖片。優(yōu)秀的開源庫在性能上往往都考慮得很仔細脸秽。
  • 最后的問題來了儒老,如果只想寫一個小demo,不愿大張旗鼓怎么辦记餐?如果即便一般的第三方庫也不好解決問題贷盲,比如上一篇那個該死的loadIcon()方法返回的是一個Drawable對象,GlidePicasso都沒法直接處理,轉碼又等于添了個耗時任務巩剖,那怎么辦铝穷?
真正的app管理應用,應該引入UIL或者Picasso一類的加載庫進行圖標加載
(在此原諒博主沒仔細敲代碼佳魔,就信口開河了)

答案就是曙聂,想法在你setAdapter之前就把任務給完成

Demo

喲西鞠鲜,上代碼宁脊!本文代碼完全基于上一篇文,無須刪減重構贤姆。
主要就是增添了一個實體bean對象榆苞,setAdapter()時要傳遞的數(shù)據(jù),全部通過它預先加載到內存里霞捡!這樣那倆敏感方法里只需要簡單的get出來即可坐漏。

實體類AppBean.java

package com.example.jin.localapp;
import android.graphics.drawable.Drawable;

/**
 * Created by Jin on 2016/11/8.
 */
public class AppBean {
    private CharSequence name;
    private String packageName;
    private Drawable icon;
    //這類代碼可別逞英雄手動寫哦,IDE(Android Studio和Eclipse都有的)里可以直接生成
    public CharSequence getName() {
        return name;
    }
    public void setName(CharSequence name) {
        this.name = name;
    }
    public String getPackageName() {
        return packageName;
    }
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }
    public Drawable getIcon() {
        return icon;
    }
    public void setIcon(Drawable icon) {
        this.icon = icon;
    }
}

主界面MainActivity.java

    private List<AppBean> mList;//mList的泛型換成AppBean
    private void initData() {//然后只需要改這個方法
        mList = new ArrayList<>();
        manager = getPackageManager();
        List<PackageInfo> list = manager.getInstalledPackages(0);//獲取已安裝的全部應用
        for (PackageInfo info : list) {
            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                AppBean bean = new AppBean();
                bean.setName(info.applicationInfo.loadLabel(manager));
                bean.setPackageName(info.packageName);
                bean.setIcon(info.applicationInfo.loadIcon(manager));
                mList.add(bean);
            }
        }
        //拿到數(shù)據(jù)再setAdapter
        mainRcv.setLayoutManager(new LinearLayoutManager(this));
        mainRcv.setHasFixedSize(true);
        mainRcv.setAdapter(new AppAdapter(this, mList));
    }

適配器AppAdapter.java

    private List<AppBean> appList;
    //同樣這邊的類型換過來
    public AppAdapter(Context context, List<AppBean> appList) {
        this.context = context;
        this.appList = appList;
        inflater = LayoutInflater.from(context);
        manager = context.getPackageManager();
    }
    //然后也只需要改這個方法
    @Override
    public void onBindViewHolder(AppHolder holder, final int position) {
        final AppBean bean = appList.get(position);
        holder.itemIconIv.setImageDrawable(bean.getIcon());//圖標
        holder.itemNameTv.setText(bean.getName());//名稱
        holder.itemPackageTv.setText(bean.getPackageName());//包名

        holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(manager.getLaunchIntentForPackage(bean.getPackageName()));//根據(jù)包名啟動此應用
                context.startActivity(intent);
            }
        });
    }

搞定碧信!因為博主是用手機直接錄像再轉gif赊琳,為了使點擊看上去有效果,于是給item增添了一個背景層砰碴,這需求實戰(zhàn)中也是很常見的哦~~

色彩資源文件colors.xml

這個粉紅色其實很難看躏筏,單純當區(qū)別用。呈枉。趁尼。。猖辫。弱卡。
實戰(zhàn)開發(fā)如果沒有美工,一定要仔細斟酌選取住册,盡量讓自己審美好點婶博!
推薦一個不錯的配色方案網站Material Design調色板

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorWhite">#ffffff</color>
    <color name="colorPink">#f8bbd0</color>

</resources>

選擇器item_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@color/colorWhite"  />  
    <item android:state_focused="true" android:drawable="@color/colorPink"  />  
    <item android:state_pressed="true" android:drawable="@color/colorPink"  />
    <item android:drawable="@color/colorWhite"/>

</selector>

條目布局item_app.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/item_selector"
    android:layout_width="match_parent"
    android:layout_height="60dp">

<!-- 中間內容無須修改,略-->

</RelativeLayout>

最終運行效果

截圖已經不太能感受到卡了荧飞,真機運行更加流暢凡人!

1.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叹阔,隨后出現(xiàn)的幾起案子挠轴,更是在濱河造成了極大的恐慌,老刑警劉巖耳幢,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岸晦,死亡現(xiàn)場離奇詭異欧啤,居然都是意外死亡,警方通過查閱死者的電腦和手機启上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門邢隧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冈在,你說我怎么就攤上這事倒慧。” “怎么了包券?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵纫谅,是天一觀的道長。 經常有香客問我溅固,道長付秕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任侍郭,我火速辦了婚禮询吴,結果婚禮上,老公的妹妹穿的比我還像新娘励幼。我一直安慰自己,他們只是感情好口柳,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布苹粟。 她就那樣靜靜地躺著,像睡著了一般跃闹。 火紅的嫁衣襯著肌膚如雪嵌削。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天望艺,我揣著相機與錄音苛秕,去河邊找鬼。 笑死找默,一個胖子當著我的面吹牛艇劫,可吹牛的內容都是我干的。 我是一名探鬼主播惩激,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼店煞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了风钻?” 一聲冷哼從身側響起顷蟀,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎骡技,沒想到半個月后鸣个,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年囤萤,在試婚紗的時候發(fā)現(xiàn)自己被綠了昼窗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡阁将,死狀恐怖膏秫,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情做盅,我是刑警寧澤缤削,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站吹榴,受9級特大地震影響亭敢,放射性物質發(fā)生泄漏。R本人自食惡果不足惜图筹,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一帅刀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧远剩,春花似錦扣溺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痢掠,卻和暖如春驱犹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背足画。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工雄驹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淹辞。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓医舆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親象缀。 傳聞我的和親對象是個殘疾皇子彬向,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,754評論 25 707
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,409評論 2 45
  • 簡介: 提供一個讓有限的窗口變成一個大數(shù)據(jù)集的靈活視圖攻冷。 術語表: Adapter:RecyclerView的子類...
    酷泡泡閱讀 5,148評論 0 16
  • 天南地北其意是我在南娃胆,你在北,雖然望著同一片星空等曼,記憶喚起無遐的漣漪里烦,心里的訴聲卻如波浪無法控制凿蒜,翻腔而來? 六月...
    咕嚕_fc3f閱讀 265評論 0 2
  • 已經坐在位置上,思考自己今天該寫什么共80分鐘零六秒丧蘸,手機也只剩余百分之二十的電量漂洋。希望一切都停止,除了自己的大腦...
    譽曉花香閱讀 408評論 0 0