ViewPager 可回收的adapter

雖說 ViewPager 以及 提供了 緩存的機制,
可以通過 mViewPager.setOffscreenPageLimit(4);
來設置緩存的頁數

當然 還有一些特殊情況 爲了性能的考略,  需要 回收一些View
而不是每次 緩存一頁數據 都是從新加載.

其實也是 模仿ListView 的 holder 來緩存View 的

直接看代碼吧: 

public class RecommendViewPageAdapter extends PagerAdapter {
    public static final String TAG = "RecommendViewPageAdapter";

    private Context mContext;
    private List<TopicModel> mTopicModels;
    private List<ViewHolder> mViewHolderList = new ArrayList<>();

    public RecommendViewPageAdapter(Context context, List<TopicModel> models) {
        mContext = context;
        mTopicModels = models;
    }

    @Override
    public int getCount() {
        return mTopicModels.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((ViewHolder) object).itemView;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        final ViewHolder viewHolder;
        if (mViewHolderList.size() > 0) {
            viewHolder = mViewHolderList.get(0);
            mViewHolderList.remove(0);
        } else {
            final View item = LayoutInflater.from(mContext).inflate(R.layout.recommend_view_pager_item, null);
            viewHolder = new ViewHolder(item);
        }

        final TopicModel headerTopic = mTopicModels.get(position);

        viewHolder.mCoverImg.setImageURI(headerTopic.getBigCoverUri());
        viewHolder.mTitleTxt.setText(headerTopic.getTitle());
        viewHolder.mRankingTxt.setText(mContext.getResources().getString(R.string.ranking_count, headerTopic.getArticleNum()));
        viewHolder.mFollowTxt.setText(mContext.getResources().getString(R.string.followed, headerTopic.getFollowUserNum()));

        viewHolder.mTagsLinearLayout.removeAllViews();
        for (int i = 0, z = headerTopic.getTagModelList().size(); i < z; i++) {
            TextView tagTxtView = TagViewUtil.getTagTxtView(mContext);
//            tagTxtView.setText("標籤");
            int padding = mContext.getResources().getDimensionPixelOffset(R.dimen.item_padding_micro);
            int autoPadding = AutoUtils.scaleValue(padding);
            AutoWrapLinearLayout.LayoutParams layoutParams = new AutoWrapLinearLayout.LayoutParams(autoPadding, autoPadding);
            tagTxtView.setText(headerTopic.getTagModelList().get(i).getTag());
            viewHolder.mTagsLinearLayout.addView(tagTxtView, layoutParams);
        }

        container.addView(viewHolder.itemView, -1, null);

        if (mOnItemClickListener != null) {
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onClick(viewHolder.itemView, headerTopic, position);
                }
            });
        }
        return viewHolder;
    }

    public static class ViewHolder {

        public View itemView;

        @Bind(R.id.img_cover)
        SimpleDraweeView mCoverImg;

        @Bind(R.id.txt_title)
        TextView mTitleTxt;

        @Bind(R.id.tags_box)
        AutoWrapLinearLayout mTagsLinearLayout;

        @Bind(R.id.txt_ranking)
        TextView mRankingTxt;

        @Bind(R.id.txt_follow)
        TextView mFollowTxt;

        public ViewHolder(View itemView) {
            this.itemView = itemView;
            ButterKnife.bind(this, itemView);
        }
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        LogUtil.d(TAG, "destroyItem position = " + position + " , obj = " + object);
        ViewHolder viewHolder = (ViewHolder) object;
        (container).removeView(viewHolder.itemView);
        mViewHolderList.add(viewHolder);
        container.removeView(viewHolder.itemView);
    }

    OnItemClickListener mOnItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener {
        void onClick(View view, TopicModel headerTopic, int position);
    }
}


在 destroyItem 方法中  把View 緩存 
然後 instantiateItem 放在中 判斷是否有緩存的View  有的話 重複利用

還有一點需要注意的是:

getItemPosition 方法 返回 POSITION_NONE,
再調用 adapter.notifyDataSetChanged() 時 纔會 刷新整個ViewPager 會 destroy 調用所有Item 然後從新加載

關於  爲什麼返回 POSITION_NONE 可以產考 這片文章:


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