RecyclerView自定義點擊事件和長按事件

RecyclerView 是Android L版本中新添加的一個用來取代ListView的SDK,它的靈活性與可替代性比listview更好。接下來通過一系列的文章講解如何使用RecyclerView,徹底拋棄ListView(如有不周,純屬謬論)。

首先gradle引入依賴庫,列表的每一個Item我這使用的是CardView所以還需引入CardView庫

compile 'com.android.support:design:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'

佈局聲明

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

先添加一些測試數據,方便測試

private void initData() {
        list = new ArrayList<>();
        for (int i = 1; i <= 50; i++) {
            CellData cellData = new CellData("我是標題" + i, "我是內容" + i);
            list.add(cellData);
        }
    }

RecyclerView跟ListView不同的一點就是需要我們爲其指定佈局管理器,用來確定每一個item如何進行排列擺放,何時展示和隱藏。

目前SDK中提供了三種自帶的LayoutManager:
 1.LinearLayoutManager
 2.GridLayoutManager
 3.StaggeredGridLayoutManager

//線性佈局,第一個參數不用說,第二個容器的走向,第三個時候反轉意思就是以中間爲對稱軸左右兩邊互換。
 LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);

 //網格佈局,第一個參數不用說,第二個容器的行數和列數,第三個容器走向,第四個同上。
 GridLayoutManager manager = new GridLayoutManager(this, 6, GridLayoutManager.HORIZONTAL, false);

 //爲RecyclerView設置LayoutManger
 mRecyclerView.setLayoutManager(manager);

 //設置item固定大小
 mRecyclerView.setHasFixedSize(true);

設置適配器和數據

 MyAdapter mAdapter = new MyAdapter(list);
            mRecyclerView.setAdapter(mAdapter);

我們都知道ListView需要我們去寫一個ViewHolder用來管理視圖,同樣RecyclerView也需要一個ViewHolder,不過這裏源碼已經幫我我們定義好了我們只需要寫一個自己的類來繼承RecyclerView.ViewHolder就可以了

//視圖管理者
public class ViewHolder extends RecyclerView.ViewHolder {

        private TextView title, content;
        private View root;

        public ViewHolder(View root) {
            super(root);
            this.root = root;
            title = (TextView) root.findViewById(R.id.tv_title);
            content = (TextView) root.findViewById(R.id.tv_content);
        }
    }

繼承RecyclerView.Adapter

//返回Item條數
@Override
    public int getItemCount() {
        return list.size();
    }
//創建視圖管理者,初始化我們的列表Item佈局,這裏同時還設置了列表的點擊和長按事件。
//因爲官方沒有爲我們寫好這兩個事件,所以需要我們自定義了。
@Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_success, parent, false);
        ViewHolder vh = new ViewHolder(root);
        //爲Item設置點擊事件,以整個item作爲可點擊的對象
        root.setOnClickListener(this);
        root.setOnLongClickListener(this);
        return vh;
    }
//綁定視圖管理者
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.title.setText(list.get(position).getTitle());
        holder.content.setText(list.get(position).getContent());
        //設置Tag,方便等下進行點擊事件數據的處理
        holder.root.setTag(position);
    }

接下來就爲我們的Item設置點擊事件了,需要我們自己定義兩個接口來實現

//點擊事件
public interface RecyclerViewOnItemClickListener {

        void onItemClickListener(View view, int position);

    }
    //長按事件
    public interface RecyclerViewOnItemLongClickListener {

        boolean onItemLongClickListener(View view, int position);

    }

放上整個Adapter代碼,這樣看起來就更清晰一些。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
        implements View.OnClickListener, View.OnLongClickListener {

    private List<CellData> list;

    public MyAdapter(List<CellData> list) {
        this.list = list;
    }

    private RecyclerViewOnItemClickListener onItemClickListener;
    private RecyclerViewOnItemLongClickListener onItemLongClickListener;


    public class ViewHolder extends RecyclerView.ViewHolder {

        private TextView title, content;
        private View root;

        public ViewHolder(View root) {
            super(root);
            this.root = root;
            title = (TextView) root.findViewById(R.id.tv_title);
            content = (TextView) root.findViewById(R.id.tv_content);
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    //綁定視圖管理者
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.title.setText(list.get(position).getTitle());
        //設置Tag
        holder.content.setText(list.get(position).getContent());
        holder.root.setTag(position);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_success, parent, false);
        ViewHolder vh = new ViewHolder(root);
        //爲Item設置點擊事件
        root.setOnClickListener(this);
        root.setOnLongClickListener(this);
        return vh;
    }

    @Override
    public void onClick(View v) {
        if (onItemClickListener != null) {
            //注意這裏使用getTag方法獲取數據
            onItemClickListener.onItemClickListener(v, (Integer) v.getTag());
        }
    }

    @Override
    public boolean onLongClick(View v) {
        return onItemLongClickListener != null && onItemLongClickListener.onItemLongClickListener(v, (Integer) v.getTag());
    }

    /*設置點擊事件*/
    public void setRecyclerViewOnItemClickListener(RecyclerViewOnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    /*設置長按事件*/
    public void setOnItemLongClickListener(RecyclerViewOnItemLongClickListener onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
    }

    public interface RecyclerViewOnItemClickListener {

        void onItemClickListener(View view, int position);

    }

    public interface RecyclerViewOnItemLongClickListener {

        boolean onItemLongClickListener(View view, int position);

    }
}

然後就是MainActivity對這兩個事件的監聽了

//設置RecyclerView的每一項的點擊事件
            mAdapter.setRecyclerViewOnItemClickListener(new MyAdapter.RecyclerViewOnItemClickListener() {
                @Override
                public void onItemClickListener(View view, int position) {
                    Snackbar.make(view, "點擊事件:" + list.get(position).getContent(), Snackbar.LENGTH_SHORT).show();
                }
            });

            //設置RecyclerView的每一項的長按事件
            mAdapter.setOnItemLongClickListener(new MyAdapter.RecyclerViewOnItemLongClickListener() {
                @Override
                public boolean onItemLongClickListener(View view, int position) {
                    Snackbar.make(view, "長按事件:" + list.get(position).getContent(), Snackbar.LENGTH_SHORT).show();
                    return true;
                }
            });

瞄一下Item佈局,這裏面就用到了CardView了,可以讓你的app看起來更加美觀,待會看下效果圖。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_marginBottom="@dimen/activity_vertical_margin"
    android:layout_marginLeft="@dimen/activity_horizontal_margin"
    android:layout_marginRight="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    card_view:cardBackgroundColor="#fffefe"
    card_view:cardCornerRadius="10dp"
    card_view:contentPadding="5dp">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginTop="50dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#364b37" />
</android.support.v7.widget.CardView>

效果圖由於電腦比較卡,所以錄製的圖片有點卡頓實際效果還是很不錯的。
這裏寫圖片描述
以上就是對RecyclerView的一個簡單使用,它既然是用來取代ListView的那用處肯定就不止這些,例如可以對Item進行拖拽排序,瀑布流等等。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章