天天看點

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

1. 概述

       官方介紹,RecyclerView用于在有限的視窗展現大量的資料,其實早已經有了類似的控件,如ListView、GridView,那麼相比它們,RecyclerView有什麼樣優勢呢? 

RecyclerView标準化了ViewHolder,而且異常的靈活,可以輕松實作ListView實作不了的樣式和功能,通過布局管理器LayoutManager可控制Item的布局方式,通過設定Item操作動畫自定義Item添加和删除的動畫,通過設定Item之間的間隔樣式,自定義間隔。

  • 設定布局管理器以控制Item的布局方式,橫向、豎向以及瀑布流方式。
  • 可設定Item操作的動畫(删除或者添加等)
  • 可設定Item的間隔樣式(可繪制)

但是關于Item的點選和長按事件,需要使用者自己去實作。

       在使用RecyclerView時候,必須指定一個擴充卡Adapter和一個布局管理器LayoutManager。擴充卡繼承

RecyclerView.Adapter

類,具體實作類似ListView的擴充卡,取決于資料資訊以及展示的UI。布局管理器用于确定RecyclerView中Item的展示方式以及決定何時複用已經不可見的Item,避免重複建立以及執行高成本的

findViewById()

方法。

來看一下用法。

mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// 設定布局管理器
mRecyclerView.setLayoutManager(mLayoutManager);
// 設定adapter
mRecyclerView.setAdapter(mAdapter);
// 設定Item添加和移除的動畫
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
// 設定Item之間間隔樣式
mRecyclerView.addItemDecoration(mDividerItemDecoration);           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

       可以看見RecyclerView相比ListView會多出許多操作,這也是RecyclerView靈活的地方,它将許多動能暴露出來,使用者可以選擇性的自定義屬性以滿足需求。

RecyclerView提供了三種布局管理器:

  • LinerLayoutManager 以垂直或者水準清單方式展示Item
  • GridLayoutManager 以網格方式展示Item
  • StaggeredGridLayoutManager 以瀑布流方式展示Item

2. 基本使用

在build.gradle檔案中引入該類。

compile 'com.android.support:recyclerview-v7:23.4.0'           
  • 1
  • 1

Activity代碼

public class MDRvActivity extends MDBaseActivity {

    private RecyclerView mRecyclerView;

    private RecyclerView.Adapter mAdapter;

    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rv);
        initData();
        initView();
    }

    private void initData() {
        mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mAdapter = new MyAdapter(getData());
    }

    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // 設定布局管理器
        mRecyclerView.setLayoutManager(mLayoutManager);
        // 設定adapter
        mRecyclerView.setAdapter(mAdapter);
    }

    private ArrayList<String> getData() {
        ArrayList<String> data = new ArrayList<>();
        String temp = " item";
        for(int i = ; i < ; i++) {
            data.add(i + temp);
        }

        return data;
    }
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

Activity布局檔案activity_rv.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

RecyclerView擴充卡Adapter代碼

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{

    private ArrayList<String> mData;

    public MyAdapter(ArrayList<String> data) {
        this.mData = data;
    }

    public void updateData(ArrayList<String> data) {
        this.mData = data;
        notifyDataSetChanged();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 執行個體化展示的view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_rv_item, parent, false);
        // 執行個體化viewholder
        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // 綁定資料
        holder.mTv.setText(mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData == null ?  : mData.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTv;

        public ViewHolder(View itemView) {
            super(itemView);
            mTv = (TextView) itemView.findViewById(R.id.item_tv);
        }
    }
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

Item的布局檔案view_rv_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="@dimen/md_common_view_height">
    <TextView
        android:id="@+id/item_tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        tools:text="item"/>
</LinearLayout>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

運作結果如下:

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

圖-1 RecyclerView無間隔

       可以看見展示效果和ListView基本上無差别,但是Item之間并沒有分割線,在xml去找divider屬性的時候,發現RecyclerView沒有divider屬性,當然也可以在Item布局中加上分割線,但是這樣做并不是很優雅。前文說過,RecyclerView可是支援自定義間隔樣式的。通過

mRecyclerView.addItemDecoration()

來設定我們定義好的間隔樣式。

3. 間隔樣式

自定義間隔樣式需要繼承

RecyclerView.ItemDecoration

類,該類是個抽象類,主要有三個方法。

  • onDraw(Canvas c, RecyclerView parent, State state),在Item繪制之前被調用,該方法主要用于繪制間隔樣式
  • onDrawOver(Canvas c, RecyclerView parent, State state),在Item繪制之前被調用,該方法主要用于繪制間隔樣式
  • getItemOffsets(Rect outRect, View view, RecyclerView parent, State state),設定item的偏移量,偏移的部分用于填充間隔樣式,在RecyclerView的

    onMesure()

    中會調用該方法

onDraw()

onDrawOver()

這兩個方法都是用于繪制間隔樣式,我們隻需要複寫其中一個方法即可。直接來看一下自定義的間隔樣式的實作吧,參考官方執行個體。

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
    /**
     * 用于繪制間隔樣式
     */
    private Drawable mDivider;
    /**
     * 清單的方向,水準/豎直
     */
    private int mOrientation;


    public MyDividerItemDecoration(Context context, int orientation) {
        // 擷取預設主題的屬性
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable();
        a.recycle();
        setOrientation(orientation);
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        // 繪制間隔
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(, , , mDivider.getIntrinsicHeight());
        } else {
            outRect.set(, , mDivider.getIntrinsicWidth(), );
        }
    }

    private void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    /**
     * 繪制間隔
     */
    private void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();
        for (int i = ; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin +
                    Math.round(ViewCompat.getTranslationY(child));
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    /**
     * 繪制間隔
     */
    private void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();
        final int childCount = parent.getChildCount();
        for (int i = ; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin +
                    Math.round(ViewCompat.getTranslationX(child));
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

然後在代碼中設定RecyclerView的間隔樣式。

mRecyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL));           
  • 1
  • 1

來看一下展示效果。

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

圖-2 RecyclerView有間隔

既然RecyclerView還支援水準清單,簡單改一下屬性,看看水準清單的顯示效果。

修改Item的布局檔案view_rv_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="@dimen/md_common_view_width"
              android:layout_height="match_parent">
    <TextView
        android:id="@+id/item_tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"

        tools:text="item"/>
</LinearLayout>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

修改LayoutManager的初始化和間隔樣式初始化。

mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
// 設定Item之間間隔樣式
mRecyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.HORIZONTAL));           
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

看一下水準清單效果。

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

圖-3 RecyclerView水準清單

3. 動畫設定

       前面說過,RecyclerView可以設定清單中Item删除和添加的動畫,在v7包中給我們提供了一種預設的Item删除和添加的動畫,如果沒有特殊的需求,預設使用這個動畫即可。

// 設定Item添加和移除的動畫
mRecyclerView.setItemAnimator(new DefaultItemAnimator());           
  • 1
  • 2
  • 1
  • 2

下面就添加一下删除和添加Item的動作。在Adapter裡面添加方法。

public void addNewItem() {
    if(mData == null) {
        mData = new ArrayList<>();
    }
    mData.add(, "new Item");
    notifyItemInserted();
}

public void deleteItem() {
    if(mData == null || mData.isEmpty()) {
        return;
    }
    mData.remove();
    notifyItemRemoved();
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

添加事件的處理。

public void onClick(View v) {
    int id = v.getId();
    if(id == R.id.rv_add_item_btn) {
        mAdapter.addNewItem();
        // 由于Adapter内部是直接在首個Item位置做增加操作,增加完畢後清單移動到首個Item位置
        mLayoutManager.scrollToPosition();
    } else if(id == R.id.rv_del_item_btn){
        mAdapter.deleteItem();
        // 由于Adapter内部是直接在首個Item位置做删除操作,删除完畢後清單移動到首個Item位置
        mLayoutManager.scrollToPosition();
    }
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

準備工作完畢後,來看一下運作的效果。

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

圖-4 RecyclerView動畫

4. 點選事件

       RecyclerView并沒有像ListView一樣暴露出Item點選事件或者長按事件處理的api,也就是說使用RecyclerView時候,需要我們自己來實作Item的點選和長按等事件的處理。實作方法有很多,可以監聽RecyclerView的Touch事件然後判斷手勢做相應的處理,也可以通過在綁定ViewHolder的時候設定監聽,然後通過Apater回調出去,我們選擇第二種方法,更加直覺和簡單。

看一下Adapter的完整代碼。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{

    /**
     * 展示資料
     */
    private ArrayList<String> mData;

    /**
     * 事件回調監聽
     */
    private MyAdapter.OnItemClickListener onItemClickListener;

    public MyAdapter(ArrayList<String> data) {
        this.mData = data;
    }

    public void updateData(ArrayList<String> data) {
        this.mData = data;
        notifyDataSetChanged();
    }

    /**
     * 添加新的Item
     */
    public void addNewItem() {
        if(mData == null) {
            mData = new ArrayList<>();
        }
        mData.add(, "new Item");
        notifyItemInserted();
    }

    /**
     * 删除Item
     */
    public void deleteItem() {
        if(mData == null || mData.isEmpty()) {
            return;
        }
        mData.remove();
        notifyItemRemoved();
    }

    /**
     * 設定回調監聽
     * 
     * @param listener
     */
    public void setOnItemClickListener(MyAdapter.OnItemClickListener listener) {
        this.onItemClickListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 執行個體化展示的view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_rv_item, parent, false);
        // 執行個體化viewholder
        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        // 綁定資料
        holder.mTv.setText(mData.get(position));

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                if(onItemClickListener != null) {
                    int pos = holder.getLayoutPosition();
                    onItemClickListener.onItemClick(holder.itemView, pos);
                }
            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if(onItemClickListener != null) {
                    int pos = holder.getLayoutPosition();
                    onItemClickListener.onItemLongClick(holder.itemView, pos);
                }
                //表示此事件已經消費,不會觸發單擊事件
                return true;
            }
        });
    }

    @Override
    public int getItemCount() {
        return mData == null ?  : mData.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTv;

        public ViewHolder(View itemView) {
            super(itemView);
            mTv = (TextView) itemView.findViewById(R.id.item_tv);
        }
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
        void onItemLongClick(View view, int position);
    }
}           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109

設定Adapter的事件監聽。

mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(MDRvActivity.this,"click " + position + " item", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(View view, int position) {
        Toast.makeText(MDRvActivity.this,"long click " + position + " item", Toast.LENGTH_SHORT).show();
    }
});           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最後的實作效果。

Android開發技術研究--RecyclerView使用完全解析(一)(用RecyclerView代替ListView)

圖-5 RecyclerView點選效果

5. 總結

       可以看見相比于ListView,RecyclerView非常靈活,但其實這篇文章隻是介紹了RecyclerView的基本使用,并沒有深入,比如像網格展示和瀑布流展示都沒有介紹,而且這篇文章為了詳細的介紹使用方法,貼了大量的源代碼,導緻篇幅過長,不得以要将RecyclerView的使用分好幾篇來介紹。就目前而言,我們已經知道RecyclerView的一些功能如下。

  • 水準清單展示,設定LayoutManager的方向性
  • 豎直清單展示,設定LayoutManager的方向性
  • 自定義間隔,RecyclerView.addItemDecoration()
  • Item添加和删除動畫,RecyclerView.setItemAnimator()

       是以在項目中如果再遇見清單類的布局,就可以優先考慮使用RecyclerView,更靈活更快捷的使用方式會給編碼帶來不一樣的體驗。如果你以為這些就是RecyclerView相比ListView/GridView優勢的話,那就大錯特錯了,關于RecyclerView還有更多靈活的功能,在後面文章會慢慢介紹。

附上Demo位址:https://github.com/Kyogirante/MaterialDesignDemo

在下一篇會主要介紹RecyclerView的其他兩種展示方式,網格和瀑布流。

原文出處:http://blog.csdn.net/xiaohanluo/article/details/52191868