RecyclerView使用詳解


使用RecyclerView要引用對應的jar包,但最新版的項目中,不用引用也可以使用。

implementation 'com.android.support:recyclerview-v7:27.1.1'

RecyclerView.Adapter

首先在界面定義一個RecyclerView。

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView_frist"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true">
​
        </androidx.recyclerview.widget.RecyclerView>
​
    </LinearLayout>

然后定義一個RecyclerView的ItemView的模板,即每行的模板。

<?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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">
​
        
        <TextView
            android:id="@+id/item_tttt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text=""
            android:textColor="@color/black" />
​
        <TextView
            android:id="@+id/item_bbbb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text=""
            android:textColor="@color/black" />
​
​
</LinearLayout>

然后在代碼中配置RecyclerView的Adapter(適配器)。

 List<Cache_User> list= new ArrayList<Cache_User>();
        for(int i=0; i<10;i++){
            Cache_User user=new Cache_User();
            user.setName("test"+i);
​
            list.add(user);
        }
        binding.recyclerViewfrist.setLayoutManager(new LinearLayoutManager(this.getContext()));//這里用線性顯示 類似於listview
        //binding.recyclerViewfrist.setLayoutManager(new GridLayoutManager(this, 2));//這里用線性宮格顯示 類似於grid view
        //binding.recyclerViewfrist.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL));//這里用線性宮格顯示 類似於瀑布流 
        binding.recyclerViewfrist.setAdapter(new NormalRecyclerViewAdapter(this.getContext(),list));

如上代碼,首先定義一個對象的集合,然后設置RecyclerView的排列模式為線型縱向(LinearLayout默認是縱向)。

然后編寫NormalRecyclerViewAdapter適配器。

首先定義適配器類繼承RecyclerView.Adapter。

然后定義構造函數接受兩個參數,一個是Activity的Context,一個的列表數據。

因為,列表每次滑動都刷清空數據,所以必須在適配器里把數據進行緩存。

在RecyclerView的每一行創建時,會先觸發onCreateViewHolder,我們先在onCreateViewHolder里把每一行使用的模板XML設定一下,使用 LayoutInflater.from(context).inflate(R.layout.recyclerview_frist, parent, false)。然后把返回的view用NormalViewHolder封裝一下,將view保存起來。(NormalViewHolder繼承ViewHolder)

然后在每一行綁定數據時會觸發onBindViewHolder,我們在onBindViewHolder里把他默認提供的入參ViewHolder,轉換會NormalViewHolder,這樣我們就可以得到這一行的view了,然后通過view.findViewById找到這一行的全部控件,在通過position參數,在數據列表entityList中定位到這一行應該綁定的數據,然后將控件進行賦值。

這樣就實現了RecyclerView數據的緩存。

代碼如下:

public class NormalRecyclerViewAdapter extends RecyclerView.Adapter {
    private Context context;
    private List<Cache_User> entityList;
​
    public NormalRecyclerViewAdapter (Context context, List<Cache_User> entityList){
        this.context = context;
        this.entityList = entityList;
    }
​
    @NotNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.recyclerview_frist, parent, false);
        NormalViewHolder rh = new NormalViewHolder(view);
        return rh;
    }
​
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onBindViewHolder(@NotNull RecyclerView.ViewHolder holder, int position) {
        Cache_User entity = entityList.get(position);
        View view =  ((NormalViewHolder)holder).itemView;
//        ImageView im = (ImageView) view.findViewById(R.id.imageHeader);
​
        TextView tv = (TextView) view.findViewById(R.id.item_tttt);
        tv.setText(entity.name);
    }
​
    @Override
    public int getItemCount() {
        return entityList.size();
    }
    private class NormalViewHolder  extends RecyclerView.ViewHolder  {
​
        public View itemView;
        public NormalViewHolder(View _itemView) {
            super(_itemView);
            itemView = _itemView;
        }
    }
}

BaseQuickAdapter

BaseQuickAdapter比起RecyclerView.Adapter有一定的代碼優化,但還是要一個列表對應一個適配器。

引用BaseQuickAdapter的包,要版本3以上。

implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4"

RecyclerView的使用方式都一樣,都是頁面先使用RecyclerView,然后在代碼中寫RecyclerView的配置。

SFragmentAdapter adapter = new SFragmentAdapter(this.getContext(),list);
         binding.recyclerViewS.setLayoutManager(new LinearLayoutManager(this.getContext()));//這里用線性顯示 類似於listview
         binding.recyclerViewS.setAdapter(adapter);
         OnItemChildClickListener listener = (listenerAdapter, view, position) -> {
            Cache_User user = list.get(position);
​
            switch (view.getId()) {
                case R.id.btnLook:
                    ((BaseActivity)getActivity()).ShowMessage_Snackbar(root,"fdfd");
                    break;
​
            }
        };
        adapter.addChildClickViewIds(R.id.btnLook);//為行內按鈕注冊點擊事件
        adapter.setOnItemChildClickListener(listener);//注冊整個點擊事件

如上代碼所示,使用了BaseQuickAdapter的子類SFragmentAdapter,進行配置RecyclerView。

配置完成后,又使用BaseQuickAdapter的子類的對象實現行內按鈕的點擊事件。

然后編寫BaseQuickAdapter的子類SFragmentAdapter。

public class SFragmentAdapter extends BaseQuickAdapter<Cache_User, BaseViewHolder> {
    private Context context;
​
    public SFragmentAdapter(@Nullable Context _context, @Nullable List<Cache_User>  data) {
        super(R.layout.recyclerview_surveyfragment, data);
        this.context=_context;
    }
    @Override
    protected void convert(BaseViewHolder helper, Cache_User item) {
​
        helper.setText(R.id.name,"姓名:"+item.name);
        helper.setText(R.id.loginName,"登錄名:"+item.loginName);
        helper.setText(R.id.realId,"真實ID:"+item.realId);
        helper.setText(R.id.id,"ID:"+item.id);
    }
}

如上所示,在BaseQuickAdapter的子類中,我們只需要重寫一個convert方法就可以了。

BaseViewHolder提供兩個參數,一個是ViewHolder,他返回的是BaseViewHolder類型的ViewHolder,一個是當前行的實體。然后什么使用BaseViewHolder提供的函數,對當前行內的控件賦值,就實現了數據緩存。

代碼相對比RecyclerView.Adapter簡單一點。

PS1:默認的Style設置為帶的Bridge的【Theme.MaterialComponents.Light.NoActionBar.Bridge】時,按鈕樣式才受自定義控制。

PS2:this表示類的實例,通常Activity內部this就是Activity本身的實例,但如果是方法內部this就會表示這個方法所有類的實例,比如在Activity內部做一個Http請求,那么Http請求的回調函數中,this就是不是Activity的實例了,而如此此時需要跳轉頁面,而Intent的入參需要Activity,那么就需要使用Activity.this來獲取實例

<style name="Theme.Survey" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">

----------------------------------------------------------------------------------------------------

注:此文章為原創,任何形式的轉載都請聯系作者獲得授權並注明出處!
若您覺得這篇文章還不錯,請點擊下方的推薦】,非常感謝!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM