1. 程式人生 > >Android RecyclerView比較常用的使用方法總結

Android RecyclerView比較常用的使用方法總結

(點選上方目錄可以跳轉)
轉載請註明出處:http://blog.csdn.net/htwhtw123/article/details/77917403
1.一般的RecyclerView(和一些注意事項)
2.下拉後從上端重新整理
3.上拉從下端重新整理
4.新增尾部首部分別新增footer和Head
專案Demo放在gihub上了,4個module是此博文的4個情況下的例項點選跳轉

1.一般的RecyclerView(和一些注意事項)

(在demo中是名為Normal的module)
1.首先需要匯入RecyclerView,下面給兩種方法,任選一種(方法一是匯入包的共有方法,感覺匯入官方包時更加常用)
(1)方法一:ctrl+shift+alt+s->左端點選需要匯入RecyclerViewd的module->右上端點選Dependencies標籤->點選最右端加號:“+”
->library dependency->搜尋框輸入recyclerView後回車->雙擊以“com.android.“開頭的一項->OK
(2)方法二:在module的build.gradle中的dependencies {}中新增下面一句後點擊Android Studio右上角出現的Sync Now。

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'

2.佈局檔案,沒有什麼特殊的

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

3.列表子項的佈局,一定要注意,最外層的控制元件高度不是match_parent,而是子項需要有的高度,否則一個子項就會佔據整個螢幕。這裡就放了一個textView,其實想放什麼控制元件都可以,在介面卡裡面,這些物件都是可以獲取的,在那裡怎麼設定都可以。這裡通過android:layout_marginTop=”4dp”,實現子項間有4dp的間隔,可以通過設定顏色,實現recyclerView的分隔線(當然還有更加正規的方法)。下面是item_layout的全部程式碼。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_marginTop="4dp"
              android:background="@android:color/white"
              android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/textView" android:textSize="30sp" android:padding="5dp" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView"/> </LinearLayout>

4.RecyclerView的介面卡需要重寫,可以依照自己的需求修改,這裡寫一個常用的,並可以對recyclerView資料新增、刪除、清空的介面卡。下面直接放ItemAdapter裡的程式碼:

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.MyViewHolder> {

    List<String> list;//存放資料
    Context context;

    public ItemAdapter(List<String> list, Context context) {
        this.list = list;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false));
        return holder;
    }

    //在這裡可以獲得每個子項裡面的控制元件的例項,比如這裡的TextView,子項本身的例項是itemView,
// 在這裡對獲取物件進行操作
    //holder.itemView是子項檢視的例項,holder.textView是子項內控制元件的例項
    //position是點選位置
    @Override
    public void onBindViewHolder(MyViewHolder holder,final  int position) {
    //設定textView顯示內容為list裡的對應項
        holder.textView.setText(list.get(position));
        //子項的點選事件監聽
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "點選子項"+position, Toast.LENGTH_SHORT).show();
            }
        });
    }

//要顯示的子項數量
    @Override
    public int getItemCount() {
        return list.size();
    }

    //這裡定義的是子項的類,不要在這裡直接對獲取物件進行操作
    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView textView;

        public MyViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
        }
    }

    /*之下的方法都是為了方便操作,並不是必須的*/

    //在指定位置插入,原位置的向後移動一格
    public boolean addItem(int position, String msg) {
        if (position < list.size() && position >= 0) {
            list.add(position, msg);
            notifyItemInserted(position);
            return true;
        }
        return false;
    }

    //去除指定位置的子項
    public boolean removeItem(int position) {
        if (position < list.size() && position >= 0) {
            list.remove(position);
            notifyItemRemoved(position);
            return true;
        }
        return false;
    }

    //清空顯示資料
    public void clearAll() {
        list.clear();
        notifyDataSetChanged();
    }

5.Activity裡的程式碼:RecyclerView的三部曲:獲取recyclerView物件、添加布局管理器、新增介面卡。介面卡要重寫,可以事先放入資料,也可以之後新增資料。注意,這裡匯入包是import android.support.v7.widget.RecyclerView; 不要匯入另一個。

 RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);//獲取物件
        recyclerView.setLayoutManager(new LinearLayoutManager(this));//設定佈局管理器,這裡選擇用豎直的列表
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            list.add("" + i);
        }
        ItemAdapter itemAdapter=new ItemAdapter(list, this);//新增介面卡,這裡介面卡剛剛裝入了資料
        recyclerView.setAdapter(itemAdapter);
        //itemAdapter.addItem(1,"123");
        //itemAdapter.removeItem(15);
        //itemAdapter.clearAll();

2.下拉後從上端重新整理

(在demo中是名為PullDownRefresh的module)
下拉從上端重新整理,這個比較簡單。在佈局檔案裡,用SwipeRefreshLayout把RecyclerView包在裡面,然後再在java程式碼裡面寫下拉的響應事件就好了。下面直接寫程式碼:
1.佈局檔案,把RecyclerView放在SwipeRefreshLayout裡:

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/srl"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

2.java程式碼:

  //列表
        recyclerView= (RecyclerView) findViewById(R.id.rv);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //新增資料
        list=new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("第"+i+"項");
        }
        adapter=new ItemAdapter(list,this);
        recyclerView.setAdapter(adapter);

        //下拉載入控制元件
        swipeRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.srl);
        swipeRefreshLayout.setColorSchemeColors(Color.BLUE);//設定旋轉圈的顏色
        //下拉監聽
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                list.add(0,"下拉加載出現的:"+i++);
                adapter.notifyDataSetChanged();
                swipeRefreshLayout.setRefreshing(false);//設定成true的話,下拉過後就會一直在那裡轉
            }
        });

(在demo中是名為PullUpRefresh的module)

3.上拉從下端重新整理

設定一個監聽器,在上拉到開始顯示最下面一項時,載入更多項。
監聽器EndLessOnScrollListener程式碼:


public abstract class EndLessOnScrollListener extends RecyclerView.OnScrollListener {

    private static final String TAG = "EndLessOnScrollListener";

    LinearLayoutManager linearLayoutManager;

    //當前所在頁
    private int currentPage=0;

    //已經加載出來的item數
    private int totalItemCount=0;

    //用來儲存上一個totalItemCount
    private int previousTotal=0;

    //螢幕可見的item數量
    private int visibleItemCount;

    //螢幕可見第一個Item的位置
    private int firstVisibleItem;

    //是否上拉資料
    private boolean loading=true;

    public EndLessOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.linearLayoutManager = linearLayoutManager;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount=recyclerView.getChildCount();
        totalItemCount=linearLayoutManager.getItemCount();
        firstVisibleItem=linearLayoutManager.findFirstVisibleItemPosition();
//去掉loading也可以,但是效能會下降,在每次滑動時都會判斷,所以的加上
        if(loading){
            Log.d(TAG, "firstVisibleItem: " + firstVisibleItem);
            Log.d(TAG, "totalItemCount:" + totalItemCount);
            Log.d(TAG, "visibleItemCount:" + visibleItemCount);
            Log.d(TAG, "currentPage:" + currentPage);
            if(totalItemCount>previousTotal){
                //說明資料項已經載入結束
                loading=false;
                previousTotal=totalItemCount;
            }
        }
        //實際效果是滑動到已載入頁最後一項可見的瞬間,新增下一頁
        if(!loading&&totalItemCount-visibleItemCount<=firstVisibleItem){
            currentPage++;
            onLoadMore(currentPage);
            loading=true;
        }

    }

    /**
     * 提供一個抽閒方法,在Activity中監聽到這個EndLessOnScrollListener
     * 並且實現這個方法
     * 這個方法在可見的頁的最後一項,可見時呼叫
     * currentPage是載入到的頁面編號
     */
    public abstract void onLoadMore(int currentPage);

給recyclerview新增上拉監聽事件即可,這裡我讓它每次加5項:

  recyclerView.addOnScrollListener(new EndLessOnScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore(int currentPage) {
                for (int i = count; i < 5+count; i++) {
                    list.add("上拉載入"+i);
                }
                adapter.notifyDataSetChanged();
                count+=5;
            }
        });

4.新增尾部首部分別新增footer和Head

(在demo中是名為HeaderAndFooter的module)
實現方法,主要是在介面卡裡實現。要在介面卡必須寫的方法裡面和getItemViewType()方法裡,考慮可能最前和最後一項分別是header和footer情況。

1.temAdapter裡的程式碼


    private static final int TYPE_HEADER = 0;
    private static final int TYPE_FOOTER = 1;
    private static final int TYPE_NORMAL = 2;


    public ItemAdapter(List<String> list, Context context) {
        this.list = list;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (headerView != null && viewType == TYPE_HEADER) {
            return new MyViewHolder(headerView);
        }
        if (footerView != null && viewType == TYPE_FOOTER) {
            return new MyViewHolder(footerView);
        }

        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).
                inflate(R.layout.item_layout, parent, false));
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        if (getItemViewType(position) == TYPE_NORMAL) {
            holder.tv.setText(list.get(position - 1));
            return;
        } else if (getItemViewType(position) == TYPE_HEADER) {
            return;
        } else
            return;
    }

    /**
     * 重寫這個方法,很重要,是加入Header和Footer的關鍵,我們通過判斷item的型別,從而繫結不同的view
     */
    @Override
    public int getItemViewType(int position) {
        if (headerView == null && footerView == null) {
            return TYPE_NORMAL;
        }
        if (position == 0) {
            //第一個item應該載入Header
            return TYPE_HEADER;
        }
        if (position == getItemCount() - 1) {
            //最後一個,應該載入Footer
            return TYPE_FOOTER;
        }
        return TYPE_NORMAL;
    }

    @Override
    public int getItemCount() {
        if (headerView == null && footerView == null) {
            return list.size();
        } else if (headerView == null && footerView != null) {
            return list.size() + 1;
        } else if (headerView != null && footerView == null) {
            return list.size() + 1;
        } else {
            return list.size() + 2;
        }
    }

    public View getHeaderView() {
        return headerView;
    }

    public void setHeaderView(View headerView) {
        this.headerView=headerView;
        notifyItemInserted(0);
    }

    public View getFooterView() {
        return footerView;
    }

    public void setFooterView(View footerView) {
        this.footerView=footerView;
        notifyItemInserted(getItemCount()-1);
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv;

        public MyViewHolder(View itemView) {
            super(itemView);
            tv = itemView.findViewById(R.id.tv);
        }
    }

活動裡面的程式碼:

RecyclerView recyclerView;
    ItemAdapter adapter;
    List<String>list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
 private void initView() {
        list= new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("第"+i+"項");
        }
        adapter=new ItemAdapter(list,this);

        recyclerView= (RecyclerView) findViewById(R.id.rv);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //注意,以下兩個方法必須在setAdapter()之後呼叫,否則長和寬會變成wrap_content
        addHeader();
        addFooter();

    }

    private void addHeader(){
        View header= LayoutInflater.from(this).inflate(R.layout.header_layout,recyclerView,false);
        adapter.setHeaderView(header);
    }

    private  void addFooter(){
        View footer= LayoutInflater.from(this).inflate(R.layout.footer_layout,recyclerView,false);
        adapter.setFooterView(footer);
    }

相關推薦

Android RecyclerView比較常用的使用方法總結

(點選上方目錄可以跳轉) 轉載請註明出處:http://blog.csdn.net/htwhtw123/article/details/77917403 1.一般的RecyclerView(和一些注意事項) 2.下拉後從上端重新整理 3.上拉從下端重新整

RecyclerView常用方法;工作原理與ListView比較;原始碼解析

寫在前面 本文原創,轉載請以連結形式註明地址:http://kymjs.com/code/2016/07/10/01起深入淺出這名字的時候我是慎重又慎重的,生怕被人罵標題黨,寫的什麼破玩意還敢說深入淺出。所以還是請大家不要抱著太高的期望,因為沒有期望就沒有失望,就像陳潤說的

C# Winform 跨線程更新UI控件常用方法總結(轉)

sum tex ase adc 而是 this obj 出現 turn 出處:http://www.tuicool.com/articles/FNzURb 概述 C#Winform編程中,跨線程直接更新UI控件的做法是不正確的,會時常出現“線程間操作無效: 從不是創建控件的

day2 字符串常用方法總結

mes 一個 並且 lun int() join() eba false 換行符 字符串在Python中是常用的功能,我們知道,字符串在Python中存儲的形式是以字符數組的形式存在,比如"alex"在內存中的存儲形式是:["a","l","e","x"],因為我們

javascript字符串屬性及常用方法總結

ring 方法總結 search lower 指定 you 數組 參數 world length屬性:str.length; 常用方法: 1. str.charAt(n) 查找字符串中的第n個字符,如果不在0~str.length-1之間,則返回一個空字符串 2 .st

JOptionPane類提示框常用方法總結

border input bfc 返回 dia conf cin chm 執行 JOptionPane類封裝了很多的方法,總結如下: 1、showMessageDialog 顯示一個帶有OK 按鈕的模態對話框。 下面是幾個使用showMessageDialog 的例子:

C# 文件操作常用方法總結

arch 擴展 追加 內容 cto 源文件 pen only lin 需引用  System.IO Path為絕對路徑 檢測指定目錄是否存在  Directory.Exists(Path) 創建目錄  Directory.CreateDirectory(Path

JS常用方法總結

ber 解析 單詞 tin js sort rep 無法 lac 瀏覽器 1.javascript刪除元素節點   IE中有這樣一個方法:removeNode(),這個方法在IE下是好使的,但是在Firefox等標準瀏覽器中就會報錯了 removeNode is not

Python Selenium 常用方法總結

display hand 刪除 chrom width attr esc ctrl sage 1.獲取當前頁面的Url 方法:current_url 實例:driver.current_url 2.獲取元素坐標 方法:location 解釋:首先查找到你要

基於字符串的常用方法總結

包含 空字符串 總結 字符 tar 提取 大於 sub 空字符 str.substring(start,end) str的字符的index是從0開始的,返回包含start到end-1的str的子字符串 沒有start也沒有end則返回str 沒有end或end比str.le

Collections常用方法總結

sat 最小值 binary pan lis nts 常用 lac string public class CollectionsTest { public static void main(String[] args) { List<In

JavaScript 常用方法總結

onload ase move 1.7 component tac typeof 小白 ie 8 var BrowserInfo = {userAgent: navigator.userAgent.toLowerCase()isAndroid: Boolean(naviga

Python 字符串常用方法總結

style sdi 括號 16px 空格 精度 意思 字符 dst 明確:對字符串的操作方法都不會改變原來字符串的值 1,去掉空格和特殊符號 name.strip() 去掉空格和換行符 name.strip(‘xx‘) 去掉某個字符串 name.lstrip() 去掉

python os模塊常用方法總結

rmdir src dst 系統信息 nbsp isf pre os模塊 text 該模塊提供一種便捷的方式來操作系統 os.environ:返回系統環境變量 os.getenv(env):返回環境變量env的值 os.getpid():當前程序的進程 os.uname(

js字符串常用方法總結

總結 方法 一個 兩個 asc color 指定 mit str 1、str.length——獲取字符串長度(字符串屬性) 1 var str = ‘JavaScript‘; 2 str.length; // 10 2、str.charAt(index)——返回字符串的

Python Selenium 常用方法總結(不斷補充)

hand 常用方法 ctrl str 但是 最後一個元素 orm 選擇 輸入 還有此篇內容也豐富Selenium常見元素定位方法和操作的學習介紹 selenium Python 總結一些工作中可能會經常使用到的API。 1.獲取當前頁面的Url 方法:current_u

js中數組常用方法總結

dds 設置 布爾 nsh border 方式 cal AR 操作數 前言 從事前端到現在也有快兩年了,平時也會收集整理一些筆記放在印象筆記,不過收集過之後就在沒有看過,經大佬指點,真正掌握一個知識點,最好的方式就是用自己的話把內容講明白,就開始將以前零散的東西整合一下,和

js數組常用方法總結

mod reducer length 方法 指定 box 但是 map pre 最近工作中經常用到數組操作,每次都傻傻不知道怎麽用,今天有時間整理了一下,希望對大家有幫助!這些基礎的知識,要熟記於心。 1、 join() 功能:將數組中所有元素都轉化為字符串並連接在一起

001_JavaScript數組常用方法總結及使用案例

convert ava ip地址轉換 java mas str 轉換 TP ads 一、 https://msdn.microsoft.com/zh-cn/library/ff679976(v=vs.94).aspx 二、ip地址轉換成對應的二進制. const ip=‘

bash shell 中時間操作常用方法總結

hour day 當前時間 簡單的 之前 nbsp seconds 獲取 相互   在日常的工作中,bash shell 的時間操作非常頻繁。比如shell腳本定時發送數據統計的時候,會查看當前是否為預定的發送時間。或者使用文件保存一些數據時,一般會生成時間字符串當做文