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