RecyclerView的使用+相關(guān)問題

前言:RecyclerView是Android中一個(gè)強(qiáng)大的控件浪藻,它可以用于展示大量的數(shù)據(jù)列表捐迫,同時(shí)也可以支持多種布局類型和動(dòng)畫效果。使用RecyclerView可以提高應(yīng)用程序的性能和用戶體驗(yàn)爱葵。那么施戴,它究竟是如何使用的呢反浓?關(guān)于它的使用又會(huì)出現(xiàn)什么問題呢?下面隨小編一起來看一看赞哗。

一勾习、如何使用RecyclerView

1.在布局文件中添加RecyclerView控件:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
//省略一些布局條件
  1. 創(chuàng)建一個(gè)Adapter類,繼承自RecyclerView.Adapter懈玻,并實(shí)現(xiàn)以下方法:
  • onCreateViewHolder:創(chuàng)建ViewHolder對象巧婶,并返回。
  • onBindViewHolder:將數(shù)據(jù)綁定到ViewHolder對象上涂乌。
  • getItemCount:返回?cái)?shù)據(jù)的數(shù)量艺栈。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private List<String> mData;

    public MyAdapter(List<String> data) {
        mData = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTextView.setText(mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mTextView = itemView.findViewById(R.id.text_view);
        }
    }
}
  • onCreateViewHolder():每當(dāng) RecyclerView 需要?jiǎng)?chuàng)建新的 ViewHolder 時(shí),它都會(huì)調(diào)用此方法湾盒。此方法會(huì)創(chuàng)建并初始化ViewHolder`及其關(guān)聯(lián)的 View湿右,但不會(huì)填充視圖的內(nèi)容,因?yàn)?ViewHolder此時(shí)尚未綁定到具體數(shù)據(jù)罚勾。
  • onBindViewHolder():RecyclerView調(diào)用此方法將 ViewHolder與數(shù)據(jù)相關(guān)聯(lián)毅人。此方法會(huì)提取適當(dāng)?shù)臄?shù)據(jù),并使用該數(shù)據(jù)填充 ViewHolder 的布局尖殃。例如丈莺,如果 RecyclerView 顯示的是一個(gè)名稱列表,該方法可能會(huì)在列表中查找適當(dāng)?shù)拿Q送丰,并填充 ViewHolder 的 TextView.widget缔俄。
  • getItemCount():RecyclerView 調(diào)用此方法來獲取數(shù)據(jù)集的大小。例如器躏,在通訊簿應(yīng)用中俐载,這可能是地址總數(shù)。RecyclerView 使用此方法來確定什么時(shí)候沒有更多的列表項(xiàng)可以顯示登失。
  1. 在Activity或者Fragment中遏佣,初始化RecyclerView控件,并設(shè)置Adapter和LayoutManager:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter adapter = new MyAdapter(data);
recyclerView.setAdapter(adapter);

其中揽浙,LayoutManager用于控制RecyclerView中子項(xiàng)的布局方式状婶,常用的有LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager(瀑布流)等捏萍。

  1. 如果需要添加點(diǎn)擊事件或者動(dòng)畫效果太抓,可以在Adapter中實(shí)現(xiàn)相應(yīng)的方法空闲,并在ViewHolder中添加相應(yīng)的控件和事件處理:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private List<String> mData;
    private OnItemClickListener mListener;

    public MyAdapter(List<String> data) {
        mData = data;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mTextView.setText(mData.get(position));
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onItemClick(position);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mTextView = itemView.findViewById(R.id.text_view);
        }
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
    }
}
  1. 在Activity或者Fragment中令杈,可以通過setOnItemClickListener方法設(shè)置點(diǎn)擊事件:
adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(int position) {
        // 處理點(diǎn)擊事件
    }
});

二、什么是ViewHolder碴倾?

ViewHolder是RecyclerView中的一個(gè)重要概念逗噩,它主要用于緩存item中的控件掉丽,避免重復(fù)獲取和findViewById,從而提高RecyclerView的性能异雁。

在RecyclerView中捶障,每個(gè)item都是一個(gè)ViewHolder,它包含了item中的所有控件纲刀。當(dāng)RecyclerView需要顯示一個(gè)新的item時(shí)项炼,它會(huì)調(diào)用Adapter的onCreateViewHolder方法創(chuàng)建一個(gè)新的ViewHolder,并將item中的控件保存在ViewHolder中示绊。當(dāng)RecyclerView需要更新item時(shí)锭部,它會(huì)調(diào)用Adapter的onBindViewHolder方法將數(shù)據(jù)綁定到ViewHolder中的控件上。

ViewHolder的實(shí)現(xiàn)通常是一個(gè)靜態(tài)內(nèi)部類面褐,它繼承自RecyclerView.ViewHolder拌禾,并包含了item中的所有控件。ViewHolder的構(gòu)造方法通常只接收一個(gè)參數(shù)展哭,即item的根布局湃窍。

三、相關(guān)問題

在使用RecyclerView時(shí)匪傍,我們可能會(huì)遇到一些問題:

  1. 布局錯(cuò)亂
    當(dāng)RecyclerView中的item布局復(fù)雜或者嵌套層次較深時(shí)您市,可能會(huì)出現(xiàn)布局錯(cuò)亂的情況。這時(shí)可以嘗試使用ConstraintLayout等布局控件役衡,或者在ViewHolder中使用setIsRecyclable(false)禁用ViewHolder的回收機(jī)制墨坚。
  2. 內(nèi)存泄漏
    當(dāng)ViewHolder中的控件持有Activity或Fragment的引用時(shí),可能會(huì)導(dǎo)致內(nèi)存泄漏映挂。這時(shí)可以嘗試使用靜態(tài)內(nèi)部類或者弱引用來解決泽篮。
  3. 列表滑動(dòng)卡頓
    當(dāng)RecyclerView中的item數(shù)量較多或者item布局較復(fù)雜時(shí),可能會(huì)導(dǎo)致列表滑動(dòng)卡頓柑船。這時(shí)可以嘗試使用RecyclerView的優(yōu)化措施帽撑,如使用ViewHolder、使用分頁加載鞍时、使用異步加載亏拉、使用圖片緩存等。
  4. 數(shù)據(jù)更新不及時(shí)
    當(dāng)RecyclerView中的數(shù)據(jù)發(fā)生變化時(shí)逆巍,可能會(huì)導(dǎo)致數(shù)據(jù)更新不及時(shí)及塘。這時(shí)可以嘗試調(diào)用Adapter的notifyDataSetChanged方法或者notifyItemChanged方法來更新數(shù)據(jù)。
  5. 多種布局混用
    當(dāng)RecyclerView中需要使用多種布局時(shí)锐极,可能會(huì)出現(xiàn)混亂或者重復(fù)的情況笙僚。這時(shí)可以嘗試使用RecyclerView的多布局類型功能,即通過getItemViewType方法返回不同的布局類型灵再。

四肋层、如何解決scollview與recyclerview之間的滑動(dòng)沖突

當(dāng)手指在ScrollView和RecyclerView之間滑動(dòng)時(shí)亿笤,可能會(huì)出現(xiàn)滑動(dòng)沖突,造成用戶體驗(yàn)不佳栋猖,為解決ScrollView和RecyclerView之間的滑動(dòng)沖突净薛,可以采取以下兩種方式:

  1. 禁止ScrollView的滑動(dòng)事件(或禁止RecyclerView同理):
    在ScrollView中,可以通過重寫onInterceptTouchEvent方法蒲拉,禁止ScrollView的滑動(dòng)事件肃拜。
  2. 使用NestedScrollView代替ScrollView:
    NestedScrollView是Android 5.0引入的新控件,它可以嵌套R(shí)ecyclerView雌团,解決了ScrollView和RecyclerView之間的滑動(dòng)沖突爆班。使用NestedScrollView和RecyclerView的方式與ScrollView和RecyclerView相同,只需要將ScrollView替換為NestedScrollView即可辱姨。

五柿菩、ListView和RecyclerView有什么區(qū)別

  1. 性能:RecyclerView相比ListView具有更好的性能,因?yàn)镽ecyclerView使用了ViewHolder的復(fù)用機(jī)制雨涛,可以避免重復(fù)創(chuàng)建和銷毀視圖枢舶,從而提高了列表的滑動(dòng)流暢度和響應(yīng)速度。
  2. 靈活性:RecyclerView的靈活性比ListView更高替久,因?yàn)镽ecyclerView支持多種布局類型凉泄、動(dòng)畫效果和ItemDecoration等功能,可以實(shí)現(xiàn)更加豐富和復(fù)雜的列表效果蚯根。
  3. 緩存:RecyclerView的緩存機(jī)制比ListView更加靈活后众,因?yàn)镽ecyclerView可以自定義緩存大小和緩存策略,可以根據(jù)實(shí)際情況進(jìn)行調(diào)整颅拦。
  4. Adapter:RecyclerView的Adapter相比ListView的Adapter更加靈活蒂誉,因?yàn)镽ecyclerView的Adapter可以自定義ViewHolder、布局類型和數(shù)據(jù)源等距帅,可以滿足更加復(fù)雜的列表需求右锨。
  5. 處理大數(shù)據(jù)量:RecyclerView比ListView更適合處理大數(shù)據(jù)量的列表,因?yàn)镽ecyclerView支持分頁加載和異步加載等功能碌秸,可以避免一次性加載大量數(shù)據(jù)導(dǎo)致內(nèi)存溢出等問題绍移。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市讥电,隨后出現(xiàn)的幾起案子蹂窖,更是在濱河造成了極大的恐慌,老刑警劉巖恩敌,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞬测,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涣楷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門分唾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抗碰,“玉大人狮斗,你說我怎么就攤上這事』∮” “怎么了碳褒?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長看疗。 經(jīng)常有香客問我沙峻,道長,這世上最難降的妖魔是什么两芳? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任摔寨,我火速辦了婚禮,結(jié)果婚禮上怖辆,老公的妹妹穿的比我還像新娘是复。我一直安慰自己,他們只是感情好竖螃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布淑廊。 她就那樣靜靜地躺著,像睡著了一般特咆。 火紅的嫁衣襯著肌膚如雪季惩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天腻格,我揣著相機(jī)與錄音画拾,去河邊找鬼。 笑死菜职,一個(gè)胖子當(dāng)著我的面吹牛碾阁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播些楣,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼脂凶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了愁茁?” 一聲冷哼從身側(cè)響起蚕钦,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹅很,沒想到半個(gè)月后嘶居,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年邮屁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了整袁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡佑吝,死狀恐怖坐昙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芋忿,我是刑警寧澤炸客,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站戈钢,受9級特大地震影響痹仙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜殉了,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一开仰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薪铜,春花似錦众弓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鞍恢,卻和暖如春傻粘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帮掉。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工弦悉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蟆炊。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓稽莉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涩搓。 傳聞我的和親對象是個(gè)殘疾皇子污秆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

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