摘要:詳細(xì)解釋簡單介紹是一個(gè)高度的解耦,異常的靈活的,通過設(shè)置它提供的不同,實(shí)現(xiàn)令人瞠目的效果。能夠顯示數(shù)據(jù)還離不開另外兩個(gè)類的支持子類和子類。會(huì)找到目標(biāo)位置的數(shù)據(jù)并綁定到的視圖上。整個(gè)過程執(zhí)行完畢,就能在屏幕上顯示列表項(xiàng)了。
RecyclerView詳細(xì)解釋 RecyclerView簡單介紹
RecyclerView是一個(gè)高度的解耦,異常的靈活的View,通過設(shè)置它提供的不同LayoutManager,ItemDecoration , ItemAnimator實(shí)現(xiàn)令人瞠目的效果。
RecyclerView與老前輩ListView的不同點(diǎn),主要在于以下幾個(gè)特性:
Adapter中的ViewHolder模式?-?對(duì)于ListView來說,通過創(chuàng)建 ViewHolder 來提升性能并不是必須的。因?yàn)長istView并沒有嚴(yán)格的ViewHolder設(shè)計(jì)模式。但是在使用RecyclerView的時(shí)候,Adapter 必須實(shí)現(xiàn)至少一個(gè)ViewHolder,必須遵循ViewHolder設(shè)計(jì)模式。
定制Item條目?-?ListView只能實(shí)現(xiàn)垂直線性排列的列表視圖,與之不同的是,RecyclerView可以通過設(shè)置RecyclerView.LayoutManager來定制不同風(fēng)格的視圖,比如水平滾動(dòng)列表或者不規(guī)則的瀑布流列表。
tem動(dòng)畫?-?在ListView中沒有提供任何方法或者接口,方便開發(fā)者實(shí)現(xiàn)Item的增刪動(dòng)畫。相反地,可以通過設(shè)置RecyclerView的 RecyclerView.ItemAnimator 來為條目增加動(dòng)畫效果。
設(shè)置數(shù)據(jù)源?-?在LisView中針對(duì)不同數(shù)據(jù)封裝了各種類型的 Adapter ,比如用來處理數(shù)組的 ArrayAdapter 和用來展示Database結(jié)果的 CursorAdapter 。相反地,在RecyclerView中必須自定義實(shí)現(xiàn) RecyclerView.Adapter 并為其提供數(shù)據(jù)集合。
設(shè)置條目分割線?-?在ListView中可以通過設(shè)置 android:divider 屬性來為兩個(gè)Item間設(shè)置分割線。如果想為RecyclerView添加此效果,則必須使用 RecyclerView.ItemDecoration ,這種實(shí)現(xiàn)方式不僅更靈活,而且樣式也更加豐富。
設(shè)置點(diǎn)擊事件?-?在ListView中存在 AdapterView.OnItemClickListener 接口,用來綁定條目的點(diǎn)擊事件。但是,很遺憾的是在RecyclerView中,并沒有提供這樣的接口,不過,提供了另外一個(gè)接口 RcyclerView.OnItemTouchListener ,用來響應(yīng)條目的觸摸事件。
RecyclerView簡單使用一個(gè)是在Gradle中直接添加:
compile "com.android.support:recyclerview-v7:24.2.1"
版本號(hào)不用找,仿照上面的appcompat直接用,把a(bǔ)ppcompat改成recyclerview即可
compile "com.android.support:appcompat-v7:24.2.1"
第二種是在Design面板直接拖拽,會(huì)提示你添加
核心類的介紹RecyclerView的任務(wù)僅限于回收和定位屏幕上的View。 View能夠顯示數(shù)據(jù)還離不
開另外兩個(gè)類的支持:Adapter子類和ViewHolder子類。
RecyclerView.Adapter ?-?處理數(shù)據(jù)集合并負(fù)責(zé)綁定視圖
ViewHolder ?-?持有所有的用于綁定數(shù)據(jù)或者需要操作的View
LayoutManager ?-?負(fù)責(zé)擺放視圖等相關(guān)操作
ItemDecoration ?-?負(fù)責(zé)繪制Item附近的分割線
ItemAnimator ?-?為Item的一般操作添加動(dòng)畫效果,如,增刪條目等
ViewHolderViewHolder只做一件事:容納View視圖
RecyclerView自身不會(huì)創(chuàng)建視圖,它創(chuàng)建的是ViewHolder,而ViewHolder引用著一個(gè)個(gè)
itemView,如下圖:
可以通過打印 ViewHolder.toString 來獲取更多有效信息
@Override public String toString() { final StringBuilder sb = new StringBuilder("ViewHolder{" + Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId + ", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition); if (isScrap()) { sb.append(" scrap ") .append(mInChangeScrap ? "[changeScrap]" : "[attachedScrap]"); } if (isInvalid()) sb.append(" invalid"); if (!isBound()) sb.append(" unbound"); if (needsUpdate()) sb.append(" update"); if (isRemoved()) sb.append(" removed"); if (shouldIgnore()) sb.append(" ignored"); if (isTmpDetached()) sb.append(" tmpDetached"); if (!isRecyclable()) sb.append(" not recyclable(" + mIsRecyclableCount + ")"); if (isAdapterPositionUnknown()) sb.append(" undefined adapter position"); if (itemView.getParent() == null) sb.append(" no parent"); sb.append("}"); return sb.toString(); }Adapter
Adapter是個(gè)控制器對(duì)象,從模型層獲取數(shù)據(jù),然后提供給RecyclerView顯示,起到了溝通的橋梁作用,adapter負(fù)責(zé):
1、創(chuàng)建必要的ViewHolder;
2、 綁定ViewHolder至模型層數(shù)據(jù)。
public?VH?onCreateViewHolder(ViewGroup?parent,?int?viewType) ?創(chuàng)建Item視圖,并返回相應(yīng)的ViewHolder
public?void?onBindViewHolder(VH?holder,?int?position) ?綁定數(shù)據(jù)到正確的Item視圖上。
public?int?getItemCount() ?返回該Adapter所持有的Itme數(shù)量
要?jiǎng)?chuàng)建adapter, 首先要定義RecyclerView.Adapter子類,RecyclerView需要顯示視圖對(duì)象時(shí), 就會(huì)去找它的adapter,如下圖:
首先,通過調(diào)用adapter的getItemCount()方法,RecyclerView詢問數(shù)組列表中包含多少個(gè)
對(duì)象。
接 著 , RecyclerView 調(diào) 用 adapter 的 createViewHolder(ViewGroup, int) 方 法 創(chuàng) 建
ViewHolder以及ViewHolder要顯示的視圖。
最后, RecyclerView會(huì)傳入ViewHolder及其位置, 調(diào)用onBindViewHolder(ViewHolder,
int)方法。adapter會(huì)找到目標(biāo)位置的數(shù)據(jù)并綁定到ViewHolder的視圖上。所謂綁定,就是使用
模型數(shù)據(jù)填充視圖。
整個(gè)過程執(zhí)行完畢,RecyclerView就能在屏幕上顯示crime列表項(xiàng)了。需要注意的是,相對(duì)
于onBindViewHolder(ViewHolder, int)方法,createViewHolder(ViewGroup, int)方法
的調(diào)用并不頻繁。一旦創(chuàng)建了夠用的ViewHolder,RecyclerView就會(huì)停止調(diào)用createView
Holder(...)方法。然后,通過回收利用舊的ViewHolder節(jié)約時(shí)間和內(nèi)存。
首先創(chuàng)建一個(gè)JavaBean負(fù)責(zé)模擬數(shù)據(jù)
public class JavaBean { String name; int age; public JavaBean(String name, int age) { this.name = name; this.age = age; } }
然后在根據(jù)上面的兩種方式添加依賴,之后設(shè)置控制器:
/** * @author HaoTianYi [email protected] * @version v1.0 * @des 一個(gè)作用是初始化UI、一個(gè)是負(fù)責(zé)更新數(shù)據(jù) * @time 2016-11-10 18:54 */ public class MyHolder extends RecyclerView.ViewHolder { private TextView mTvAge; private TextView mTvName; public MyHolder(View itemView) { super(itemView); // 初始化View mTvAge = (TextView) itemView.findViewById(R.id.age); mTvName = (TextView) itemView.findViewById(R.id.name); } /** * 負(fù)責(zé)更新數(shù)據(jù)也就是刷新UI * @param bean 數(shù)據(jù) * @call 由MyAdapter的onBindViewHolder方法調(diào)用 */ public void bindData(JavaBean bean) { mTvAge.setText(" "+bean.age); mTvName.setText(bean.name); } }
設(shè)置內(nèi)容填充者:
/** * @author HaoTianYi [email protected] * @version v1.0 * @des 從模型層拿到數(shù)據(jù)并且傳遞給RecyclerView(中間人的角色) * @time 2016-11-10 18:54 */ public class MyAdapter extends RecyclerView.Adapter{ private List mBeen; public MyAdapter(List been) { mBeen = been; } @Override public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 可以從parent得到context,沒有必要在傳遞一個(gè)context參數(shù) // 這里的父布局參數(shù)是null View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null); return new MyHolder(itemView); } /** * 一旦創(chuàng)建填充滿屏幕的item之后,在滑動(dòng)item就會(huì)復(fù)用 * 也就是不再調(diào)用onCreateViewHolder而是調(diào)用onBindViewHolder * @param holder * @param position */ @Override public void onBindViewHolder(MyHolder holder, int position) { // 用控制器控制數(shù)據(jù) holder.bindData(mBeen.get(position)); } @Override public int getItemCount() { return mBeen.size(); } }
Activity的使用代碼:
public class MainActivity extends AppCompatActivity { private ListmBeen = new ArrayList (); private final String NAME = "普朗特"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { // 模擬數(shù)據(jù) for (int i = 0; i < 50; i++) { JavaBean javaBean = new JavaBean(NAME + i, i); mBeen.add(javaBean); } RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv); recyclerView.setAdapter(new MyAdapter(mBeen)); // 一定要設(shè)置布局,否則不會(huì)顯示內(nèi)容 recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this)); } }
相比ListView而言,RecyclerView的每一個(gè)類都是真是職責(zé)超級(jí)單一?。。?!
最后放上item的代碼:
布局管理LayoutManager
布局管理的基類是RecyclerView.LayoutManager(抽象類)
LinearLayoutManager 線性管理器,支持橫向、縱向。
GridLayoutManager 網(wǎng)格布局管理器
StaggeredGridLayoutManager 瀑布式布局管理器
改變上面的代碼,瞬間實(shí)現(xiàn)水平滾動(dòng):
LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this); manager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(manager);
實(shí)現(xiàn)網(wǎng)格管理器,每一行4列
recyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this,4));
瀑布流管理器,當(dāng)?shù)诙€(gè)參數(shù)設(shè)置成Vertical時(shí)和上面一樣:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
當(dāng)設(shè)置成HORIZONTAL變成水平是4行,這時(shí)是水平滑動(dòng)的,item的寬度需要注意去設(shè)置,畢竟橫向的寬度沒有約束了,應(yīng)為控件可以橫向滾動(dòng)了。,這里沒有嚴(yán)重的變形是因?yàn)樽煮w設(shè)置了大小
常用APIfindFirstVisibleItemPosition() ?返回當(dāng)前第一個(gè)可見Item的position
findFirstCompletelyVisibleItemPosition() ?返回當(dāng)前第一個(gè)完全可見Item的position
findLastVisibleItemPosition() ?返回當(dāng)前最后一個(gè)可見Item的position
findLastCompletelyVisibleItemPosition() ?返回當(dāng)前最后一個(gè)完全可見Item的position
要把每個(gè)item的高度不固定,即可實(shí)現(xiàn),首先改Adapter中的onCreateViewHolder方法
@Override public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 可以從parent得到context,沒有必要在傳遞一個(gè)context參數(shù) // 這里的父布局參數(shù)是null View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null); //設(shè)置隨機(jī)高度 int height = (int) (Math.random() * 100); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(954/4,300+height); params.setMargins(10,10,10,10); itemView.setLayoutParams(params); return new MyHolder(itemView); }
Activity中的引用代碼不變:
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(manager);
這時(shí)可以實(shí)現(xiàn),但是每一個(gè)item在一會(huì)就會(huì)改變,而且有動(dòng)畫效果
可以看到在滑動(dòng)時(shí)候會(huì)有布局的變化,重寫Adapter中的getItemViewType可以使每一個(gè)item固定
@Override public int getItemViewType(int position) { return position; }
現(xiàn)在是沒有布局變化了
分隔條RecyclerView.ItemDecoration通過設(shè)置 recyclerView.addItemDecoration(new?DividerDecoration(this)); 來改變Item之間的偏移量或者對(duì)Item進(jìn)行裝飾。
RecyclerView.ItemDecoration 是一個(gè)抽象類,可以通過重寫以下三個(gè)方法,來實(shí)現(xiàn)Item之間的偏移量或者裝飾效果:
public?void?onDraw(Canvas?c,?RecyclerView?parent) ?裝飾的繪制在Item條目繪制之前調(diào)用,所以這有可能被Item的內(nèi)容所
遮擋
public?void?onDrawOver(Canvas?c,?RecyclerView?parent) ?裝飾的繪制在Item條目繪制之后調(diào)用,因此裝飾將浮于Item之上
public? void? getItemOffsets(Rect? outRect,? int? itemPosition,? RecyclerView? parent) ? 與 padding 或 margin 類 似 ,LayoutManager在測(cè)量階段會(huì)調(diào)用該方法,計(jì)算出每一個(gè)Item的正確尺寸并設(shè)置偏移量。
public class DividerItemDecoration extends RecyclerView.ItemDecoration { /** * 設(shè)置一個(gè)屬性集合,可以在自己的attrs中自行設(shè)置 */ 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; /** * 分割符的Drawable */ private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { System.out.println("recyclerview - itemdecoration onDraw()"); if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } /** * 繪制垂直分割符(如果是垂直滑動(dòng)的話) * @param c * @param parent */ public 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 = 0; i < childCount; i++) { final View child = parent.getChildAt(i); android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); // 找出每一個(gè)分割符的距離,就是分隔符上下左右四個(gè)點(diǎn)的坐標(biāo) final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } /** * 繪制水平分割符(如果是水平滑動(dòng)的話) * @param c * @param parent */ public 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 = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { // 這個(gè)是每兩個(gè)條目之間的垂直空隙形成的矩形 outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } } }
在上面的代碼中更改Activity中的代碼:
recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL_LIST));自定義分割符
只要在attrs中添加一個(gè)android:listDivider屬性即可,其余全部是自動(dòng)生成的:
對(duì)應(yīng)的自定義divider_item.xml
最簡單的分割符
如果只是想設(shè)置一個(gè)空余的間距,在Adapter中設(shè)置margin跟少的代碼量,改變adapter中的onCreateViewHolder方法:
@Override public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 可以從parent得到context,沒有必要在傳遞一個(gè)context參數(shù) // 這里的父布局參數(shù)是null View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(parent.getWidth(),150); params.setMargins(10,10,10,10); itemView.setLayoutParams(params); return new MyHolder(itemView); }網(wǎng)格布局中的分隔符實(shí)例
參考:csdn
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[] { android.R.attr.listDivider }; private Drawable mDivider; public DividerGridItemDecoration(Context context) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); } @Override public void onDraw(Canvas c, RecyclerView parent) { drawHorizontal(c, parent); drawVertical(c, parent); } private int getSpanCount(RecyclerView parent) { // 列數(shù) int spanCount = -1; RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { spanCount = ((StaggeredGridLayoutManager) layoutManager) .getSpanCount(); } return spanCount; } public void drawHorizontal(Canvas c, RecyclerView parent) { int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getLeft() - params.leftMargin; final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawVertical(Canvas c, RecyclerView parent) { final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getTop() - params.topMargin; final int bottom = child.getBottom() + params.bottomMargin; final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,則不需要繪制右邊 { return true; } } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); if (orientation == StaggeredGridLayoutManager.VERTICAL) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,則不需要繪制右邊 { return true; } } else { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一列,則不需要繪制右邊 return true; } } return false; } private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一行,則不需要繪制底部 return true; } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); // StaggeredGridLayoutManager 且縱向滾動(dòng) if (orientation == StaggeredGridLayoutManager.VERTICAL) { childCount = childCount - childCount % spanCount; // 如果是最后一行,則不需要繪制底部 if (pos >= childCount) return true; } else // StaggeredGridLayoutManager 且橫向滾動(dòng) { // 如果是最后一行,則不需要繪制底部 if ((pos + 1) % spanCount == 0) { return true; } } } return false; } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { int spanCount = getSpanCount(parent); int childCount = parent.getAdapter().getItemCount(); if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,則不需要繪制底部 { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,則不需要繪制右邊 { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); } }動(dòng)畫RecyclerView.ItemAnimator
在Android中默認(rèn)實(shí)現(xiàn)了一個(gè) DefaultItemAnimator
ItemAnimator能夠幫助Item實(shí)現(xiàn)獨(dú)立的動(dòng)畫,ItemAnimator作觸發(fā)于以下三種事件:
1.?某條數(shù)據(jù)被插入到數(shù)據(jù)集合中
2.?從數(shù)據(jù)集合中移除某條數(shù)據(jù)
3.?更改數(shù)據(jù)集合中的某條數(shù)據(jù)
public?void?setOnItemClickListener(@Nullable?OnItemClickListener?listener) ?Item點(diǎn)擊事件監(jiān)聽
public?void?setOnItemLongClickListener(OnItemLongClickListener?listener) ?Item長按事件監(jiān)聽
首先在Adapter中設(shè)置一個(gè)回調(diào)接口,添加OnItemClickListener接口,更改onBindViewHolder方法
private OnItemClickListener mOnItemClickListener; interface OnItemClickListener { // 點(diǎn)擊事件 void onItemClick(View view, int position); // 長按事件 void onItemLongClick(View view, int position); } public void setOnItemClickLitener(OnItemClickListener mLitener) { mOnItemClickListener = mLitener; } /** * 一旦創(chuàng)建填充滿屏幕的item之后,在滑動(dòng)item就會(huì)復(fù)用 * 也就是不再調(diào)用onCreateViewHolder而是調(diào)用onBindViewHolder * * @param holder * @param position */ @Override public void onBindViewHolder(final MyHolder holder, final int position) { // 用控制器控制數(shù)據(jù) System.out.println(holder.toString()); holder.bindData(mBeen.get(position)); if (mOnItemClickListener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onItemClick(holder.itemView, position); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mOnItemClickListener.onItemLongClick(holder.itemView, position); return true; } }); } }
在Activity中設(shè)置監(jiān)聽:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv); mAdapter = new MyAdapter(mBeen); mAdapter.setOnItemClickLitener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { System.out.println("-----"+"onItemClick"+"-----"); } @Override public void onItemLongClick(View view, int position) { System.out.println("-----"+"onItemLongClick"+"-----"); } }); recyclerView.setAdapter(mAdapter);
觸發(fā)事件,可以看到結(jié)果:
作者官方博客:天意博文
參考RecyclerView
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69823.html
摘要:其實(shí)通過父類的這個(gè)方法之后會(huì)調(diào)用它的方法,這個(gè)名字熟悉自定義的童鞋都知道了。 為什么要寫這篇源碼解析呢? 我一直在說RecyclerView是一個(gè)值得深入學(xué)習(xí),甚至可以說是一門具有藝術(shù)性的控件。那到底哪里值得我們花時(shí)間去深入學(xué)習(xí)呢。沒錯(cuò)了,就是源碼的設(shè)計(jì)。但是看源碼其實(shí)是一件不簡單的事情,就拿RecyclerView的源碼來說,打開源碼一看,往下拉啊拉啊,我擦,怎么還沒到頭,汗.......
摘要:缺點(diǎn)自動(dòng)裝箱的存在意味著每一次插入都會(huì)有額外的對(duì)象創(chuàng)建。對(duì)象本身是一層額外需要被創(chuàng)建以及被垃圾回收的對(duì)象。相較于我們舍棄了和類型的放棄了并依賴于二分法查找。 目錄介紹 25.0.0.0 請(qǐng)說一下RecyclerView?adapter的作用是什么,幾個(gè)方法是做什么用的?如何理解adapter訂閱者模式? 25.0.0.1 ViewHolder的作用是什么?如何理解ViewHolder...
閱讀 3178·2021-11-23 09:51
閱讀 689·2021-10-14 09:43
閱讀 3216·2021-09-06 15:00
閱讀 2412·2019-08-30 15:54
閱讀 2567·2019-08-30 13:58
閱讀 1857·2019-08-29 13:18
閱讀 1385·2019-08-27 10:58
閱讀 522·2019-08-27 10:53