1. 程式人生 > >Recyclerview --- (一)簡單的使用

Recyclerview --- (一)簡單的使用

【記錄】記錄點滴

【需求】從最簡單的RecyclerView使用開始記錄

RecyclerView和ListView的使用非常相似:1. 匯入包;2. 建立Adapter;3. 設定RecyclerView

1. 匯入support-v7包,例如

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

2. 繼承RecyclerView.Adater,實現自定義的Adapter

public class SimpleDemoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    List<String> data;

    public SimpleDemoAdapter (List<String> data) {
        this.data = data;
    }

    /**
     * 渲染檢視,返回ViewHolder
     */
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //使用系統佈局,裡面只有一個TextView
        View v = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        TypeOne vh = new TypeOne(v);
        return vh;
    }

    /**
     * 繫結資料,設定Item內容的地方
     */
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((TypeOne)holder).tvContent.setText("position = " + position);
    }

    /**
     * 返回資料長度
     */
    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size();
    }

    /**
     * 自定義ViewHolder,後續會記錄多型別Item的實現,所以命名就叫TypeOne
     */
    class TypeOne extends RecyclerView.ViewHolder{
        public TextView tvContent;
        public TypeOne(View itemView) {
            super(itemView);
            tvContent = itemView.findViewById(android.R.id.text1);
        }
    }
}

 3. 設定RecyclerView

在Activity或者Fragment等中

adapter = new SimpleDemoAdapter(data);

//以LinearLayoutManager示例,預設垂直方向
//也可以使用new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);來指定方向
LinearLayoutManager llm = new LinearLayoutManager(context);
rv.setLayoutManager(llm);
rv.setAdapter(adapter);

PS:多種型別 Item 時,需要重寫 getItemViewType()

1)先設計一個類,其中的 type 對應 Item 的型別

public class MultiTypeRvBean {

    public int type = 0;
    public String content;

    public MultiTypeRvBean(int type, String content) {
        this.type = type;
        this.content = content;
    }
}

 2)重寫Adapter中的 getItemViewType

    //這裡簡單些,直接返回MultiType中的type,並依據type判斷
    @Override
    public int getItemViewType(int position) {
        MultiTypeRvBean bean = data.get(position);
        return bean.type;
    }

3)修改onCreateViewHolder與onBindViewHolder

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = null;
        RecyclerView.ViewHolder vh;
        switch (viewType){
            case 0:
                v = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
                vh = new TypeOne(v);
                return vh;
            case 1:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tv_center, parent, false);
                vh = new TypeTwo(v);
                return vh;
            case 2:
            default:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tv_right, parent, false);
                vh = new TypeThree(v);
                return vh;
        }

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        switch (getItemViewType(position)){
            case 0:
                ((TypeOne)holder).tvContent.setText("樣式一");
                break;
            case 1:
                ((TypeTwo)holder).tvCenter.setText("樣式二");
                break;
            case 2:
            default:
                ((TypeThree)holder).tvRight.setText("樣式三");
        }
    }

PS:巢狀使用RecyclerView,和普通使用一樣

    /**
     * 重點在這裡,0:渲染巢狀的Grid,只含有一個RecyclerView,1:渲染普通的Item,只含有一個TextView
     */
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = null;
        RecyclerView.ViewHolder vh;
        switch (viewType) {
            case 0:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_nest_recycler, parent, false);
                vh = new TypeNestRecycler(v);
                return vh;
            case 1:
            default:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tv_normal, parent, false);
                vh = new TypeNormal(v);
                return vh;

        }

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        switch (getItemViewType(position)) {
            case 0:
                GridLayoutManager glm = new GridLayoutManager(context, 3, GridLayoutManager.HORIZONTAL, false);
                SimpleGridAdapter adapter = new SimpleGridAdapter(gridData);
                ((TypeNestRecycler) holder).nestGridRv.setLayoutManager(glm);
                ((TypeNestRecycler) holder).nestGridRv.setAdapter(adapter);
                break;
            case 1:
                ((TypeNormal) holder).tvContent.setText("樣式一");
                break;
        }
    }

    /**
     * 只返回兩種型別,0 巢狀的RecyclerView,1 簡單的TextView
     */
    @Override
    public int getItemViewType(int position) {
        MultiTypeRvBean bean = data.get(position);
        return bean.type;
    }

 巢狀的RecyclerView的佈局也非常簡單item_nest_recycler.xml

<!-- item_nest_recycler.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="200dp">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/nest_grid_recycler"
        android:layout_width="match_parent"
        android:layout_height="200dp">
    </android.support.v7.widget.RecyclerView>
</LinearLayout>