RecyclerView 基本使用

原文首發(fā) http://blog.lll0.net/post/recyclerview.html

強(qiáng)大而高效的 RecyclerView

ListView作為一個(gè)強(qiáng)大而有使用頻繁的控件,但是隨著我們業(yè)務(wù)的發(fā)展慢慢的就感覺(jué) ListView 在某些業(yè)務(wù)場(chǎng)景中已經(jīng)不能滿足我們的業(yè)務(wù)需求。舉個(gè)栗子:如果我們?cè)谝粋€(gè)頁(yè)面上需要加載不同的布局,在列表中間某一行加載一個(gè)廣告試圖,而這個(gè)廣告的布局和整個(gè)個(gè)列表的布局樣式是完全不一樣的。如果放在ListView 中,這種布局是不太好實(shí)現(xiàn)的。但是放在Google 提出的新控件 ReyclerView 中 實(shí)現(xiàn)這種布局是非常簡(jiǎn)單的。

RecyclerView 是Android L版本中新添加的一個(gè)用來(lái)取代ListView的SDK,它的靈活性與可替代性比listview更好。

基本介紹

在使用RecyclerView中引入了幾個(gè)相關(guān)的類

  1. LayoutManager 用來(lái)確定每一個(gè)item如何進(jìn)行排列擺放,何時(shí)展示和隱藏?;厥栈蛑赜靡粋€(gè)View的時(shí)候,LayoutManager會(huì)向適配器請(qǐng)求新的數(shù)據(jù)來(lái)替換舊的數(shù)據(jù),這種機(jī)制避免了創(chuàng)建過(guò)多的View和頻繁的調(diào)用findViewById方法(與ListView原理類似)。Google 為我們提供了 幾個(gè)基礎(chǔ)的布局
    1. LinearLayoutManager 線性布局布局樣式和ListView一樣 呈現(xiàn)的是線性
    2. GridLayoutManager 表格布局與GridView 一樣
    3. StaggeredGridLayoutManager 瀑布流布局 這是新的布局 簡(jiǎn)單描述就是加載的每個(gè)item在頁(yè)面上占有的空間都是不一樣的布局
  2. RecyclerView.Adapter RecyclerView 的適配器 數(shù)據(jù)的加載和item 的綁定都是通過(guò)這個(gè)類來(lái)實(shí)現(xiàn)。在使用的時(shí)候需要繼承該類來(lái)進(jìn)行相應(yīng)的處理
  3. RecyclerView.ViewHolder 同樣是使用中需要繼承該類,然后進(jìn)行把數(shù)據(jù)和item里面的布局進(jìn)行綁定

在使用的時(shí)候 其實(shí)不用考慮復(fù)用的問(wèn)題。

簡(jiǎn)單使用

1.添加依賴在build.gradle 中添加依賴 ,然后同步一下 引入依賴需要的包

dependencies {
     compile 'com.android.support:recyclerview-v7:25.1.1' 
}

2.布局中使用RecylerView

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.lll0.bus.ui.test_activity.RecyclerViewTestActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="368dp"
        android:layout_height="551dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp" />
</android.support.constraint.ConstraintLayout>

3.創(chuàng)建布局之后需要在Activity中獲得這個(gè)控件,并聲明LayoutManagerAdapter,代碼如下

 mRecycler = (RecyclerView) findViewById(R.id.recycler);
 mRecycler.setLayoutManager(new LinearLayoutManager(mActitivity));
 recyclerViewAdapter = new RecyclerViewAdapter(beans,mActitivity);
 mRecycler.setAdapter(recyclerViewAdapter);

4.Adapter的創(chuàng)建

package net.lll0.bus.adapter.test;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import net.lll0.bus.suzhoubus.R;
import net.lll0.bus.adapter.RecyclerViewHolder;

import java.util.List;

/**
 * Created by liang on 2017/8/24.
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    private String typeView01 = "item1";
    private String typeView02 = "item2";
    /**
     * 加載不同的兩種方式
     * 1. 傳入不同的數(shù)據(jù)源,對(duì)應(yīng)的位置加載不同的布局
     * 2. 傳入一個(gè)數(shù)據(jù)源,但是通過(guò)數(shù)據(jù)源里面特殊的字段判斷加載什么布局
     */
    private List<Bean> bean;
    private Context mContext;
    public RecyclerViewAdapter(List<Bean> bean, Context mContext) {
        this.bean = bean;
        this.mContext = mContext;
    }
    @Override
    public int getItemViewType(int position) {
        //通過(guò)這個(gè)區(qū)分加載不同 view
        //通過(guò)判斷特殊的字段加載不同的布局

        return bean.get(position).type;
    }
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //通過(guò) getTtemViewType 返回的 內(nèi)容加載不同 的布局

        //假設(shè)加載 三中布局分別對(duì)應(yīng) 1 2 3

        if (1 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item, parent, false), viewType);
        } else if (2 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.item_lineinfo, parent, false), viewType);
        } else if (3 == viewType) {
            return new RecyclerViewHolder(mContext,LayoutInflater.from(mContext).inflate(R.layout.nav_header_home, parent, false), viewType);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        //onCreateViewHolder 為不同的布局綁定對(duì)應(yīng)的數(shù)據(jù)
        Bean bean = this.bean.get(position);
        int type = bean.type;
        if (1 == type) {
            holder.setText(R.id.textView2,"textView2");
            holder.setText(R.id.textView3,"textView3");
        } else if (2 == type) {
            holder.setText(R.id.lineinfo_index,position+"");
        } else if (3 == type) {
        }
    }
    @Override
    public int getItemCount() {
        //主要是計(jì)算 加載數(shù)據(jù)的總數(shù)
        return bean.size();
    }
}

5.RecyclerView.ViewHolder 子類的實(shí)現(xiàn) ,這是一個(gè)通用的ViewHolder

package net.lll0.bus.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
/**
 * Created by liang on 2016/2/15.
 */
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
    private SparseArray<View> mViews;//集合類,layout里包含的View,以view的id作為key,value是view對(duì)象
    private Context mContext;//上下文對(duì)象
    private int type;

    public RecyclerViewHolder(Context ctx, View itemView) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
    }
    public RecyclerViewHolder(Context ctx, View itemView,int type) {
        super(itemView);
        mContext = ctx;
        mViews = new SparseArray<View>();
        this.type = type;
    }
    public View getItemView() {
        return itemView;
    }
    /*
     * 通過(guò)空間id在SparseArray集合中找出用戶View
     * @param viewId  控件的id
     * @param <T>  具體的是那個(gè)控件
     * @return  當(dāng)然是返回你要找的控件了
     */
    private <T extends View> T findViewById(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }
    /**
     * 通過(guò)findViewById以及控件id的到用戶的空間對(duì)象
     *
     * @param viewId
     * @return
     */
    public View getView(int viewId) {
        return findViewById(viewId);
    }
    public TextView getTextView(int viewId) {
        return (TextView) getView(viewId);
    }
    public Button getButton(int viewId) {
        return (Button) getView(viewId);
    }
    public ImageView getImageView(int viewId) {
        return (ImageView) getView(viewId);
    }
    public ImageButton getImageButton(int viewId) {
        return (ImageButton) getView(viewId);
    }
    public EditText getEditText(int viewId) {
        return (EditText) getView(viewId);
    }
    public RecyclerViewHolder setText(int viewId, String value) {
        TextView view = findViewById(viewId);
        view.setText(value);
        return this;
    }
    public RecyclerViewHolder setBackground(int viewId, int resId) {
        View view = findViewById(viewId);
        view.setBackgroundResource(resId);
        return this;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    /**
     * 通過(guò)該方法可以的到對(duì)應(yīng)控件的點(diǎn)擊事件
     *
     * @param viewId   控件的id
     * @param listener 需要實(shí)現(xiàn)的監(jiān)聽(tīng)器
     * @return
     */
    public RecyclerViewHolder setClickListener(int viewId, View.OnClickListener listener) {
        View view = findViewById(viewId);
        view.setOnClickListener(listener);
        return this;
    }
}

運(yùn)行

只要實(shí)現(xiàn)以上代碼,就能實(shí)現(xiàn)具體的內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容