ListView和RecyclerView的Adapter封装
原文鏈接
Android 快速開發系列 打造萬能的ListView GridView 適配器
為RecyclerView打造通用Adapter 讓RecyclerView更加好用
Android 優雅的為RecyclerView添加HeaderView和FooterView
Android LRecyclerView實現下拉刷新,滑動到底部自動加載更多
RecyclerView添加Header的正確方式
多種ItemViewType,一般我們的寫法是:
復寫getItemViewType,根據我們的bean去返回不同的類型
onCreateViewHolder中根據itemView去生成不同的ViewHolder
如果大家還記得,我們的ViewHolder是通用的,唯一依賴的就是個layoutId。那么上述第二條就變成,根據不同的itemView告訴我用哪個layoutId即可,生成viewholder這種事我們通用adapter來做。
指明不同的Bean返回什么itemViewType,不同的itemView所對應的layoutId
LoadmoreWrapper加載更多
裝飾者模式
//設置加載更多的布局 public LoadmoreWrapper setLoadMoreView(View loadMoreView){mLoadMoreView = loadMoreView;return this;}public LoadmoreWrapper setLoadMoreView(int layoutId){mLoadMoreLayoutId = layoutId;return this;} //設置了加載更多的布局文件或者布局文件的id,則有加載更多private boolean hasLoadMore(){return mLoadMoreView != null || mLoadMoreLayoutId != 0;}//設置加載更多的布局,并且當前的位置position大于等于列表的條目數private boolean isShowLoadMore(int position){return hasLoadMore() && (position >= mInnerAdapter.getItemCount());} //如果滑動到底部,返回加載更多的itemtype@Overridepublic int getItemViewType(int position){if (isShowLoadMore(position)){return ITEM_TYPE_LOAD_MORE;}return mInnerAdapter.getItemViewType(position);} //根據不同的itemtype創建不同的viewholder @Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){if (viewType == ITEM_TYPE_LOAD_MORE){ViewHolder holder;if (mLoadMoreView != null){holder = ViewHolder.createViewHolder(parent.getContext(), mLoadMoreView);} else{holder = ViewHolder.createViewHolder(parent.getContext(), parent, mLoadMoreLayoutId);}return holder;}return mInnerAdapter.onCreateViewHolder(parent, viewType);} //如果當前的位置是加載更多的位置,則加載下一頁數據@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position){if (isShowLoadMore(position)){if (mOnLoadMoreListener != null){mOnLoadMoreListener.onLoadMoreRequested();}return;}mInnerAdapter.onBindViewHolder(holder, position);} //設置了加載更多布局,則列表條目數加1@Overridepublic int getItemCount(){return mInnerAdapter.getItemCount() + (hasLoadMore() ? 1 : 0);}LoadingFooter
public class LoadingFooter extends RelativeLayout {protected State mState = State.Normal;private View mLoadingView;private View mNetworkErrorView;private View mTheEndView;private AVLoadingIndicatorView mLoadingProgress;private TextView mLoadingText;public LoadingFooter(Context context) {super(context);init(context);}public LoadingFooter(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public LoadingFooter(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}public void init(Context context) {inflate(context, R.layout.layout_recyclerview_list_footer, this);setOnClickListener(null);setState(State.Normal, true);}public State getState() {return mState;}public void setState(State status ) {setState(status, true);}/*** 設置狀態** @param status* @param showView 是否展示當前View*/public void setState(State status, boolean showView) {if (mState == status) {return;}mState = status;switch (status) {case Normal:setOnClickListener(null);if (mLoadingView != null) {mLoadingView.setVisibility(GONE);}if (mTheEndView != null) {mTheEndView.setVisibility(GONE);}if (mNetworkErrorView != null) {mNetworkErrorView.setVisibility(GONE);}break;case Loading:setOnClickListener(null);if (mTheEndView != null) {mTheEndView.setVisibility(GONE);}if (mNetworkErrorView != null) {mNetworkErrorView.setVisibility(GONE);}if (mLoadingView == null) {ViewStub viewStub = (ViewStub) findViewById(R.id.loading_viewstub);mLoadingView = viewStub.inflate();mLoadingProgress = (AVLoadingIndicatorView) mLoadingView.findViewById(R.id.loading_progress);mLoadingText = (TextView) mLoadingView.findViewById(R.id.loading_text);} else {mLoadingView.setVisibility(VISIBLE);}mLoadingView.setVisibility(showView ? VISIBLE : GONE);mLoadingProgress.setVisibility(View.VISIBLE);mLoadingText.setText(R.string.list_footer_loading);break;case TheEnd:setOnClickListener(null);if (mLoadingView != null) {mLoadingView.setVisibility(GONE);}if (mNetworkErrorView != null) {mNetworkErrorView.setVisibility(GONE);}if (mTheEndView == null) {ViewStub viewStub = (ViewStub) findViewById(R.id.end_viewstub);mTheEndView = viewStub.inflate();} else {mTheEndView.setVisibility(VISIBLE);}mTheEndView.setVisibility(showView ? VISIBLE : GONE);break;case NetWorkError:if (mLoadingView != null) {mLoadingView.setVisibility(GONE);}if (mTheEndView != null) {mTheEndView.setVisibility(GONE);}if (mNetworkErrorView == null) {ViewStub viewStub = (ViewStub) findViewById(R.id.network_error_viewstub);mNetworkErrorView = viewStub.inflate();} else {mNetworkErrorView.setVisibility(VISIBLE);}mNetworkErrorView.setVisibility(showView ? VISIBLE : GONE);break;default:break;}}public enum State {Normal/**正常*/, TheEnd/**加載到最底了*/, Loading/**加載中..*/, NetWorkError/**網絡異常*/} }布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/loading_view"android:layout_width="match_parent"android:layout_height="@dimen/dp_60"android:gravity="center"android:orientation="vertical"><ViewStub android:id="@+id/loading_viewstub"android:layout_width="match_parent"android:layout_height="@dimen/dp_60"android:layout="@layout/layout_recyclerview_list_footer_loading" /><ViewStub android:id="@+id/end_viewstub"android:layout_width="match_parent"android:layout_height="@dimen/dp_60"android:layout="@layout/layout_recyclerview_list_footer_end" /><ViewStub android:id="@+id/network_error_viewstub"android:layout_width="match_parent"android:layout_height="@dimen/dp_60"android:layout="@layout/layout_recyclerview_list_footer_network_error" /></LinearLayout>RecyclerViewStateUtils
package com.github.jdsjlzx.util;import android.app.Activity; import android.support.v7.widget.RecyclerView; import android.view.View;import com.github.jdsjlzx.recyclerview.LRecyclerView; import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter; import com.github.jdsjlzx.view.LoadingFooter;/*** 分頁展示數據時,RecyclerView的FooterView State 操作工具類* RecyclerView一共有幾種State:Normal/Loading/Error/TheEnd** @author lizhixian* @time 16/9/10 09:56*/ public class RecyclerViewStateUtils {/*** 設置LRecyclerViewAdapter的FooterView State** @param instance context* @param recyclerView recyclerView* @param pageSize 分頁展示時,recyclerView每一頁的數量* @param state FooterView State* @param errorListener FooterView處于Error狀態時的點擊事件*/public static void setFooterViewState(Activity instance, RecyclerView recyclerView, intpageSize, LoadingFooter.State state, View.OnClickListener errorListener) {if (instance == null || instance.isFinishing()) {return;}RecyclerView.Adapter outerAdapter = recyclerView.getAdapter();if (outerAdapter == null || !(outerAdapter instanceof LRecyclerViewAdapter)) {return;}LRecyclerViewAdapter lRecyclerViewAdapter = (LRecyclerViewAdapter) outerAdapter;//只有一頁的時候,就別加什么FooterView了if (lRecyclerViewAdapter.getInnerAdapter().getItemCount() < pageSize) {return;}LoadingFooter footerView;//已經有footerView了if (lRecyclerViewAdapter.getFooterViewsCount() > 0) {footerView = (LoadingFooter) lRecyclerViewAdapter.getFooterView();footerView.setState(state);footerView.setVisibility(View.VISIBLE);if (state == LoadingFooter.State.NetWorkError) {footerView.setOnClickListener(errorListener);} else if (state == LoadingFooter.State.TheEnd) {((LRecyclerView) recyclerView).setNoMore(true);}}recyclerView.scrollToPosition(lRecyclerViewAdapter.getItemCount() - 1);}/*** 設置LRecyclerViewAdapter的FooterView State** @param instance context* @param recyclerView recyclerView* @param pageSize 分頁展示時,recyclerView每一頁的數量* @param state FooterView State* @param errorListener FooterView處于Error狀態時的點擊事件*/public static void setFooterViewState2(Activity instance, RecyclerView recyclerView, intpageSize, LoadingFooter.State state, View.OnClickListener errorListener) {if (instance == null || instance.isFinishing()) {return;}RecyclerView.Adapter outerAdapter = recyclerView.getAdapter();if (outerAdapter == null || !(outerAdapter instanceof LRecyclerViewAdapter)) {return;}LRecyclerViewAdapter lRecyclerViewAdapter = (LRecyclerViewAdapter) outerAdapter;LoadingFooter footerView;//已經有footerView了if (lRecyclerViewAdapter.getFooterViewsCount() > 0) {footerView = (LoadingFooter) lRecyclerViewAdapter.getFooterView();footerView.setState(state);if (state == LoadingFooter.State.NetWorkError) {footerView.setOnClickListener(errorListener);}recyclerView.scrollToPosition(0);} else {footerView = new LoadingFooter(instance);footerView.setState(state);if (state == LoadingFooter.State.NetWorkError) {footerView.setOnClickListener(errorListener);}lRecyclerViewAdapter.addFooterView(footerView);recyclerView.scrollToPosition(0);}}/*** 獲取當前RecyclerView.FooterView的狀態** @param recyclerView*/public static LoadingFooter.State getFooterViewState(RecyclerView recyclerView) {RecyclerView.Adapter outerAdapter = recyclerView.getAdapter();if (outerAdapter != null && outerAdapter instanceof LRecyclerViewAdapter) {if (((LRecyclerViewAdapter) outerAdapter).getFooterViewsCount() > 0) {LoadingFooter footerView = (LoadingFooter) ((LRecyclerViewAdapter) outerAdapter).getFooterView();return footerView.getState();}}return LoadingFooter.State.Normal;}/*** 設置當前RecyclerView.FooterView的狀態** @param recyclerView* @param state*/public static void setFooterViewState(RecyclerView recyclerView, LoadingFooter.State state) {RecyclerView.Adapter outerAdapter = recyclerView.getAdapter();if (outerAdapter != null && outerAdapter instanceof LRecyclerViewAdapter) {if (((LRecyclerViewAdapter) outerAdapter).getFooterViewsCount() > 0) {LoadingFooter footerView = (LoadingFooter) ((LRecyclerViewAdapter) outerAdapter).getFooterView();footerView.setState(state);}}} }LRecyclerViewAdapter
package com.github.jdsjlzx.recyclerview;import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View; import android.view.ViewGroup;import com.github.jdsjlzx.interfaces.OnItemClickListener; import com.github.jdsjlzx.interfaces.OnItemLongClickListener; import com.github.jdsjlzx.view.ArrowRefreshHeader;import java.util.ArrayList; import java.util.List;/*** RecyclerView.Adapter with Header and Footer* */ public class LRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {private static final int TYPE_REFRESH_HEADER = 10000;private static final int TYPE_NORMAL = 0;private static final int TYPE_FOOTER_VIEW = 10001;private static final int HEADER_INIT_INDEX = 10002;private static List<Integer> mHeaderTypes = new ArrayList<>();private ArrowRefreshHeader mRefreshHeader;private OnItemClickListener mOnItemClickListener;private OnItemLongClickListener mOnItemLongClickListener;/*** RecyclerView使用的,真正的Adapter*/private RecyclerView.Adapter mInnerAdapter;private ArrayList<View> mHeaderViews = new ArrayList<>();private ArrayList<View> mFooterViews = new ArrayList<>();public LRecyclerViewAdapter(RecyclerView.Adapter innerAdapter) {this.mInnerAdapter = innerAdapter;}public void setRefreshHeader(ArrowRefreshHeader refreshHeader){mRefreshHeader = refreshHeader;}public RecyclerView.Adapter getInnerAdapter() {return mInnerAdapter;}public void addHeaderView(View view) {if (view == null) {throw new RuntimeException("header is null");}mHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());mHeaderViews.add(view);}public void addFooterView(View view) {if (view == null) {throw new RuntimeException("footer is null");}if (getFooterViewsCount() > 0) {removeFooterView(getFooterView());}mFooterViews.add(view);//this.notifyDataSetChanged();}/*** 根據header的ViewType判斷是哪個header* @param itemType* @return*/private View getHeaderViewByType(int itemType) {if(!isHeaderType(itemType)) {return null;}return mHeaderViews.get(itemType - HEADER_INIT_INDEX);}/*** 判斷一個type是否為HeaderType* @param itemViewType* @return*/private boolean isHeaderType(int itemViewType) {return mHeaderViews.size() > 0 && mHeaderTypes.contains(itemViewType);}/*** 返回第一個FootView* @return*/public View getFooterView() {return getFooterViewsCount()>0 ? mFooterViews.get(0) : null;}/*** 返回第一個HeaderView* @return*/public View getHeaderView() {return getHeaderViewsCount()>0 ? mHeaderViews.get(0) : null;}public ArrayList<View> getHeaderViews() {return mHeaderViews;}public void removeHeaderView(View view) {mHeaderViews.remove(view);this.notifyDataSetChanged();}public void removeFooterView(View view) {mFooterViews.remove(view);this.notifyDataSetChanged();}public int getHeaderViewsCount() {return mHeaderViews.size();}public int getFooterViewsCount() {return mFooterViews.size();}public boolean isHeader(int position) {return position >= 1 && position < mHeaderViews.size() + 1;}public boolean isRefreshHeader(int position) {return position == 0;}public boolean isFooter(int position) {int lastPosition = getItemCount() - getFooterViewsCount();return getFooterViewsCount() > 0 && position >= lastPosition;}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {if (viewType == TYPE_REFRESH_HEADER) {return new ViewHolder(mRefreshHeader);} else if (isHeaderType(viewType)) {return new ViewHolder(getHeaderViewByType(viewType));} else if (viewType == TYPE_FOOTER_VIEW) {return new ViewHolder(mFooterViews.get(0));}return mInnerAdapter.onCreateViewHolder(parent, viewType);}@Overridepublic void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {if (isHeader(position) || isRefreshHeader(position)) {return;}final int adjPosition = position - (getHeaderViewsCount() + 1);int adapterCount;if (mInnerAdapter != null) {adapterCount = mInnerAdapter.getItemCount();if (adjPosition < adapterCount) {mInnerAdapter.onBindViewHolder(holder, adjPosition);if (mOnItemClickListener != null) {holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v){mOnItemClickListener.onItemClick(holder.itemView, adjPosition);}});}if (mOnItemLongClickListener != null) {holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v){mOnItemLongClickListener.onItemLongClick(holder.itemView, adjPosition);return true;}});}}}}@Overridepublic void onBindViewHolder(final RecyclerView.ViewHolder holder, int position, List<Object> payloads) {if (payloads.isEmpty()) {onBindViewHolder(holder,position);} else {if (isHeader(position) || isRefreshHeader(position)) {return;}final int adjPosition = position - (getHeaderViewsCount() + 1);int adapterCount;if (mInnerAdapter != null) {adapterCount = mInnerAdapter.getItemCount();if (adjPosition < adapterCount) {mInnerAdapter.onBindViewHolder(holder, adjPosition, payloads);}}}}@Overridepublic int getItemCount() {if (mInnerAdapter != null) {return getHeaderViewsCount() + getFooterViewsCount() + mInnerAdapter.getItemCount() + 1;} else {return getHeaderViewsCount() + getFooterViewsCount() + 1;}}@Overridepublic int getItemViewType(int position) {int adjPosition = position - (getHeaderViewsCount() + 1);if (isRefreshHeader(position)) {return TYPE_REFRESH_HEADER;}if (isHeader(position)) {position = position - 1;return mHeaderTypes.get(position);}if (isFooter(position)) {return TYPE_FOOTER_VIEW;}int adapterCount;if (mInnerAdapter != null) {adapterCount = mInnerAdapter.getItemCount();if (adjPosition < adapterCount) {return mInnerAdapter.getItemViewType(adjPosition);}}return TYPE_NORMAL;}@Overridepublic long getItemId(int position) {if (mInnerAdapter != null && position >= getHeaderViewsCount()) {int adjPosition = position - getHeaderViewsCount();int adapterCount = mInnerAdapter.getItemCount();if (adjPosition < adapterCount) {return mInnerAdapter.getItemId(adjPosition);}}return -1;}@Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) {super.onAttachedToRecyclerView(recyclerView);RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();if (manager instanceof GridLayoutManager) {final GridLayoutManager gridManager = ((GridLayoutManager) manager);gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {@Overridepublic int getSpanSize(int position) {return (isHeader(position) || isFooter(position) || isRefreshHeader(position))? gridManager.getSpanCount() : 1;}});}mInnerAdapter.onAttachedToRecyclerView(recyclerView);}@Overridepublic void onDetachedFromRecyclerView(RecyclerView recyclerView) {mInnerAdapter.onDetachedFromRecyclerView(recyclerView);}@Overridepublic void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {super.onViewAttachedToWindow(holder);ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {if(isHeader(holder.getLayoutPosition()) ||isRefreshHeader(holder.getLayoutPosition()) || isFooter(holder.getLayoutPosition())) {StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;p.setFullSpan(true);}}mInnerAdapter.onViewAttachedToWindow(holder);}@Overridepublic void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {mInnerAdapter.onViewDetachedFromWindow(holder);}@Overridepublic void onViewRecycled(RecyclerView.ViewHolder holder) {mInnerAdapter.onViewRecycled(holder);}public static class ViewHolder extends RecyclerView.ViewHolder {public ViewHolder(View itemView) {super(itemView);}}/**** @param isCallback whether position is from callback interface* @param position* @return*/public int getAdapterPosition(boolean isCallback, int position) {if(isCallback) {int adjPosition = position - (getHeaderViewsCount() + 1);int adapterCount = mInnerAdapter.getItemCount();if (adjPosition < adapterCount) {return adjPosition;}}else {return (position + getHeaderViewsCount()) + 1;}return -1;}public void setOnItemClickListener(OnItemClickListener itemClickListener){this.mOnItemClickListener = itemClickListener;}public void setOnItemLongClickListener(OnItemLongClickListener itemLongClickListener){this.mOnItemLongClickListener = itemLongClickListener;}}RecyclerView Cursor Adapter
原文鏈接:http://android.jobbole.com/81947/
在Android平臺中,CursorAdapter是一個適配器,用來把Cursor對象的數據展示到ListView控件里。RecyclerView適配器的第二篇將解釋如何自己構造一個簡單可重用的Cursor適配器,以及如何在你的應用中使用它。第三篇文章中,我將展示一個CursorAdapter類的更高級版本。
(相比于Android CursorAdapter,本例中用到的Cursor,不包含名為“_id”的列)
首先,我們創建一個抽象類RecyclerViewCursorAdapter,該類持有Cursor對象并實現一些RecyclerView.Adapter類需要的方法(例如getItemCount())。
而且,我們的適配器類將定義一個新的方法叫做onBindViewHolder(RecyclerView.ViewHolder, Cursor)。所以,你不需要每次獲取Cursor對象來將數據綁定到ViewHolder。
我們還增加了一些幫助方法,例如:
- swapCursor(Cursor):提供帶數據集(dataset)的適配器。
- getItem(int):獲得Cursor對象,移動到正確的位置。
- getCursor():獲得Cursor對象。
實現這個抽象類并填充數據是相當簡單的。
import android.content.Context; import android.database.Cursor; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;import butterknife.Bind; import butterknife.ButterKnife;public class SearchResultsCursorAdapter extends RecyclerViewCursorAdapter<SearchResultsCursorAdapter.SearchResultViewHolder>implements View.OnClickListener {private final LayoutInflater layoutInflater;private OnItemClickListener onItemClickListener;public SearchResultsCursorAdapter(final Context context){super();this.layoutInflater = LayoutInflater.from(context);}public void setOnItemClickListener(final OnItemClickListener onItemClickListener){this.onItemClickListener = onItemClickListener;}@Overridepublic SearchResultViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType){final View view = this.layoutInflater.inflate(R.layout.listitem_search, parent, false);view.setOnClickListener(this);return new SearchResultViewHolder(view);}@Overridepublic void onBindViewHolder(final SearchResultViewHolder holder, final Cursor cursor){holder.bindData(cursor);}/** View.OnClickListener*/@Overridepublic void onClick(final View view){if (this.onItemClickListener != null){final RecyclerView recyclerView = (RecyclerView) view.getParent();final int position = recyclerView.getChildLayoutPosition(view);if (position != RecyclerView.NO_POSITION){final Cursor cursor = this.getItem(position);this.onItemClickListener.onItemClicked(cursor);}}}public static class SearchResultViewHolder extends RecyclerView.ViewHolder{@Bind(R.id.textview_name)TextView textViewName;public SearchResultViewHolder(final View itemView){super(itemView);ButterKnife.bind(this, itemView);}public void bindData(final Cursor cursor){final String name = cursor.getString(cursor.getColumnIndex("name"));this.textViewName.setText(name);}}public interface OnItemClickListener{void onItemClicked(Cursor cursor);} }Providing the adapter with data in your Activity / Fragment:
在Activity或Fragment中提供帶數據的適配器:
import android.app.Activity; import android.app.LoaderManager; import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; import android.net.Uri; import android.os.Bundle;public class SearchActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {private static final int LOADER_SEARCH_RESULTS = 1;private SearchResultsCursorAdapter adapter;@Overrideprotected void onCreate(final Bundle savedInstanceState){super.onCreate(savedInstanceState);// create adapterthis.adapter = new SearchResultsCursorAdapter(this);// start loaderthis.getLoaderManager().restartLoader(LOADER_SEARCH_RESULTS, null, this);}@Overridepublic Loader<Cursor> onCreateLoader(final int id, final Bundle args){switch (id){case LOADER_SEARCH_RESULTS:final Uri uri = Uri.parse("content://some_uri");return new CursorLoader(this, uri, null, null, null, null);}return null;}@Overridepublic void onLoadFinished(final Loader<Cursor> loader, final Cursor data){switch (loader.getId()){case LOADER_SEARCH_RESULTS:this.adapter.swapCursor(data);break;}}@Overridepublic void onLoaderReset(final Loader<Cursor> loader){switch (loader.getId()){case LOADER_SEARCH_RESULTS:this.adapter.swapCursor(null);break;}} }總結
以上是生活随笔為你收集整理的ListView和RecyclerView的Adapter封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ViewPager+Fragment懒加
- 下一篇: ImageView scaleType