日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件

發(fā)布時間:2025/4/16 Android 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 引言:

RecyclerView側(cè)重的是布局的靈活性,雖說可以替代ListView但是連基本的點擊事件都沒有,這篇文章就來詳細(xì)講解如何為RecyclerView的item添加點擊事件,順便復(fù)習(xí)一下觀察者模式。

?

2.?最終目的

模擬ListView的setOnItemClickListener()方法,調(diào)用者只須調(diào)用類似于setOnItemClickListener的東西就能獲得被點擊item的相關(guān)數(shù)據(jù)。

?

3.?原理

為RecyclerView的每個子item設(shè)置setOnClickListener,然后在onClick中再調(diào)用一次對外封裝的接口,將這個事件傳遞給外面的調(diào)用者。而"為RecyclerView的每個子item設(shè)置setOnClickListener"在Adapter中設(shè)置。其實直接在onClick中也能完全處理item的點擊事件,但是這樣會破壞代碼的邏輯。

?

4. 具體步驟如下:

在自定義MyAdapter之中(繼承自RecyclerView.Adapter

(1)在MyAdapter中定義如下接口,模擬ListView的OnItemClickListener:

//define interfacepublic static interface OnRecyclerViewItemClickListener {void onItemClick(View view , String data);}

?

(2)聲明一個這個接口的變量

private OnRecyclerViewItemClickListener mOnItemClickListener = null;

?

(3)在onCreateViewHolder()中為每個item添加點擊事件

@Overridepublic ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);ViewHolder vh = new ViewHolder(view);//將創(chuàng)建的View注冊點擊事件view.setOnClickListener(this);return vh;}

?

(4)將點擊事件轉(zhuǎn)移給外面的調(diào)用者:

@Overridepublic void onClick(View v) {if (mOnItemClickListener != null) {//注意這里使用getTag方法獲取數(shù)據(jù) mOnItemClickListener.onItemClick(v,(String)v.getTag());}}

?

(5)注意上面調(diào)用接口的onItemClick()中的v.getTag()方法,這需要在onBindViewHolder()方法中設(shè)置和item相關(guān)的數(shù)據(jù)

@Overridepublic void onBindViewHolder(ViewHolder viewHolder, int position) {viewHolder.mTextView.setText(datas[position]);//將數(shù)據(jù)保存在itemView的Tag中,以便點擊時進(jìn)行獲取 viewHolder.itemView.setTag(datas[position]);}

(6)最后暴露給外面的調(diào)用者,定義一個設(shè)置Listener的方法():

public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {this.mOnItemClickListener = listener;}

?以上所有步驟都發(fā)生在自定義的adapter中,典型的觀察者模式,有點繞的地方在于,這里涉及到兩個觀察者模式的使用,view的setOnClickListener本來就是觀察者模式,我們將這個觀察者模式的事件監(jiān)聽傳遞給了我們自己的觀察者模式。

?

(7)接下來當(dāng)然是在Activity中使用,如下:

1 mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view); 2 //創(chuàng)建默認(rèn)的線性LayoutManager 3 mLayoutManager = new LinearLayoutManager(this); 4 mRecyclerView.setLayoutManager(mLayoutManager); 5 //如果可以確定每個item的高度是固定的,設(shè)置這個選項可以提高性能 6 mRecyclerView.setHasFixedSize(true); 7 //創(chuàng)建并設(shè)置Adapter 8 mAdapter = new MyAdapter(data); 9 mRecyclerView.setAdapter(mAdapter); 10 mAdapter.setOnItemClickListener(new OnRecyclerViewItemClickListener(){ 11 @Override 12 public void onItemClick(View view , String data){ 13 Toast.makeText(MainActivity.this, data, 600).show(); 14 } 15 });

?

5. 案例演示:(結(jié)合上面的步驟理解)

(1)使用Eclipse創(chuàng)建一個工程,如下:

同時注意API要使用API21

?

(2)首先我們來到主布局activity_main.xml,如下:

1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <android.support.v7.widget.RecyclerView 7 android:id="@+id/recyclerview" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 /> 11 12 </RelativeLayout>

(3)接下來,我們來到RecyclerView的item布局item.xml,如下:

1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="50dip" > 6 7 <TextView 8 android:id="@+id/text" 9 android:text="默認(rèn)" 10 android:layout_marginTop="5dp" 11 android:gravity="center_horizontal" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:textSize="20sp" 15 android:textColor="@android:color/holo_red_dark"/> 16 17 </RelativeLayout>

?

(4)接下來我們自定義MyAdapter,如下:

1 package com.himi.recyclerviewdemo; 2 3 import android.support.v7.widget.RecyclerView; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.TextView; 8 9 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> 10 implements View.OnClickListener { 11 12 private String[] datas; 13 14 public MyAdapter(String[] datas) { 15 this.datas = datas; 16 17 } 18 19 20 /** 21 * 1.定義接口 22 */ 23 public static interface OnRecyclerViewItemClickListener { 24 25 void onItemClick(View view, String data); 26 27 } 28 29 /** 30 * 3.在onCreateViewHolder()中為每個item添加點擊事件 31 */ 32 @Override 33 public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 34 View view = LayoutInflater.from(viewGroup.getContext()) 35 .inflate(R.layout.item, viewGroup, false); 36 37 ViewHolder vh = new ViewHolder(view); 38 // 將創(chuàng)建的View注冊點擊事件 39 view.setOnClickListener(this); 40 41 return vh; 42 } 43 44 /** 45 * 5.注意上面調(diào)用接口的onItemClick()中的v.getTag()方法, 46 * 這需要在onBindViewHolder()方法中設(shè)置和item相關(guān)的數(shù)據(jù) 47 */ 48 @Override 49 public void onBindViewHolder(ViewHolder viewHolder, int position) { 50 51 viewHolder.mTextView.setText(datas[position]); 52 53 // 將數(shù)據(jù)保存在itemView的Tag中,以便點擊時進(jìn)行獲取 54 viewHolder.itemView.setTag(datas[position]); 55 } 56 57 /** 58 * 4.將點擊事件轉(zhuǎn)移給外面的調(diào)用者 59 */ 60 public void onClick(View v) { 61 if (mOnItemClickListener != null) { 62 // 注意這里使用getTag方法獲取數(shù)據(jù) 63 mOnItemClickListener.onItemClick(v, (String) v.getTag()); 64 } 65 } 66 67 /** 68 * 2.聲明一個這個接口的變量 69 */ 70 private OnRecyclerViewItemClickListener mOnItemClickListener = null; 71 72 73 /** 74 *6.最后暴露給外面的調(diào)用者,定義一個設(shè)置Listener的方法() 75 */ 76 77 public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) { 78 this.mOnItemClickListener = listener; 79 } 80 81 82 83 // 獲取數(shù)據(jù)的數(shù)量 84 @Override 85 public int getItemCount() { 86 return datas.length; 87 } 88 89 // 自定義的ViewHolder,持有每個Item的的所有界面元素 90 public static class ViewHolder extends RecyclerView.ViewHolder { 91 public TextView mTextView; 92 93 public ViewHolder(View view) { 94 super(view); 95 mTextView = (TextView) view.findViewById(R.id.text); 96 } 97 } 98 99 }

?

(5)接下來來到MainActivity,如下:

1 package com.himi.recyclerviewdemo; 2 3 import com.himi.recyclerviewdemo.MyAdapter.OnRecyclerViewItemClickListener; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.support.v7.widget.LinearLayoutManager; 8 import android.support.v7.widget.RecyclerView; 9 import android.view.View; 10 import android.widget.Toast; 11 12 public class MainActivity extends Activity { 13 14 private RecyclerView mRecyclerView; 15 private LinearLayoutManager mLayoutManager; 16 private MyAdapter mAdapter; 17 private String[] data = new String[] { 18 "劉德華", "周杰倫", "梁朝偉", "郭富城", "黎明", "張學(xué)友", 19 "成龍", "午馬", "洪金寶", "林正英", "元彪", "林志穎", 20 "吳奇隆", "蘇有朋", "趙薇", "陳坤", "周潤發(fā)", "范冰冰", 21 "賈靜雯", "周星馳" 22 }; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); 29 30 // 創(chuàng)建默認(rèn)的線性LayoutManager 31 mLayoutManager = new LinearLayoutManager(this); 32 mRecyclerView.setLayoutManager(mLayoutManager); 33 34 // 如果可以確定每個item的高度是固定的,設(shè)置這個選項可以提高性能 35 mRecyclerView.setHasFixedSize(true); 36 37 //添加item間的分割線 38 mRecyclerView.addItemDecoration(new RecycleViewDivider(this, LinearLayoutManager.HORIZONTAL)); 39 40 // 創(chuàng)建并設(shè)置Adapter 41 mAdapter = new MyAdapter(data); 42 mRecyclerView.setAdapter(mAdapter); 43 mAdapter.setOnItemClickListener(new OnRecyclerViewItemClickListener() { 44 @Override 45 public void onItemClick(View view, String data) { 46 Toast.makeText(MainActivity.this, data, 1).show(); 47 } 48 }); 49 } 50 51 }

這里使用到的自定義分割線類RecycleViewDivider是別人寫的,我直接拿來用了,在此我表示感謝,如下:

1 package com.himi.recyclerviewdemo; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Canvas; 6 import android.graphics.Paint; 7 import android.graphics.Rect; 8 import android.graphics.drawable.Drawable; 9 import android.support.v4.content.ContextCompat; 10 import android.support.v7.widget.LinearLayoutManager; 11 import android.support.v7.widget.RecyclerView; 12 import android.support.v7.widget.RecyclerView.ItemDecoration; 13 import android.view.View; 14 15 public class RecycleViewDivider extends ItemDecoration { 16 private Paint mPaint; 17 private Drawable mDivider; 18 private int mDividerHeight = 2;//分割線高度,默認(rèn)為1px 19 private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL 20 private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; 21 22 /** 23 * 默認(rèn)分割線:高度為2px,顏色為灰色 24 * 25 * @param context 26 * @param orientation 列表方向 27 */ 28 public RecycleViewDivider(Context context, int orientation) { 29 if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { 30 throw new IllegalArgumentException("請輸入正確的參數(shù)!"); 31 } 32 mOrientation = orientation; 33 34 final TypedArray a = context.obtainStyledAttributes(ATTRS); 35 mDivider = a.getDrawable(0); 36 a.recycle(); 37 } 38 39 /** 40 * 自定義分割線 41 * 42 * @param context 43 * @param orientation 列表方向 44 * @param drawableId 分割線圖片 45 */ 46 public RecycleViewDivider(Context context, int orientation, int drawableId) { 47 this(context, orientation); 48 mDivider = ContextCompat.getDrawable(context, drawableId); 49 mDividerHeight = mDivider.getIntrinsicHeight(); 50 } 51 52 /** 53 * 自定義分割線 54 * 55 * @param context 56 * @param orientation 列表方向 57 * @param dividerHeight 分割線高度 58 * @param dividerColor 分割線顏色 59 */ 60 public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) { 61 this(context, orientation); 62 mDividerHeight = dividerHeight; 63 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 64 mPaint.setColor(dividerColor); 65 mPaint.setStyle(Paint.Style.FILL); 66 } 67 68 69 //獲取分割線尺寸 70 @Override 71 public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 72 super.getItemOffsets(outRect, view, parent, state); 73 outRect.set(0, 0, 0, mDividerHeight); 74 } 75 76 //繪制分割線 77 @Override 78 public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { 79 super.onDraw(c, parent, state); 80 if (mOrientation == LinearLayoutManager.VERTICAL) { 81 drawVertical(c, parent); 82 } else { 83 drawHorizontal(c, parent); 84 } 85 } 86 87 //繪制橫向 item 分割線 88 private void drawHorizontal(Canvas canvas, RecyclerView parent) { 89 final int left = parent.getPaddingLeft(); 90 final int right = parent.getMeasuredWidth() - parent.getPaddingRight(); 91 final int childSize = parent.getChildCount(); 92 for (int i = 0; i < childSize; i++) { 93 final View child = parent.getChildAt(i); 94 RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); 95 final int top = child.getBottom() + layoutParams.bottomMargin; 96 final int bottom = top + mDividerHeight; 97 if (mDivider != null) { 98 mDivider.setBounds(left, top, right, bottom); 99 mDivider.draw(canvas); 100 } 101 if (mPaint != null) { 102 canvas.drawRect(left, top, right, bottom, mPaint); 103 } 104 } 105 } 106 107 //繪制縱向 item 分割線 108 private void drawVertical(Canvas canvas, RecyclerView parent) { 109 final int top = parent.getPaddingTop(); 110 final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom(); 111 final int childSize = parent.getChildCount(); 112 for (int i = 0; i < childSize; i++) { 113 final View child = parent.getChildAt(i); 114 RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); 115 final int left = child.getRight() + layoutParams.rightMargin; 116 final int right = left + mDividerHeight; 117 if (mDivider != null) { 118 mDivider.setBounds(left, top, right, bottom); 119 mDivider.draw(canvas); 120 } 121 if (mPaint != null) { 122 canvas.drawRect(left, top, right, bottom, mPaint); 123 } 124 } 125 } 126 }

(6)部署程序到手機(jī)上,如下:

?

?

6. 總結(jié):

在ListView中我們是調(diào)用ListView的setOnItemClickListener:

1 mListView.setOnItemClickListener(new OnItemClickListener() { 2 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 3 4 ... 5 6 } 7 });

而在我們這里是調(diào)用mAdapter的setOnItemClickListener。且回調(diào)方法public void onItemClick()的參數(shù)也不一致,ListView中有被點擊item的position參數(shù),而我們這里直接是被點擊item的相關(guān)數(shù)據(jù)(這里只是一個字符串)。

?

轉(zhuǎn)載于:https://www.cnblogs.com/hebao0514/p/5643225.html

總結(jié)

以上是生活随笔為你收集整理的Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。