RecyclePagerAdapter-實(shí)現(xiàn)ViewPager復(fù)用回收的PagerAdapter
實(shí)現(xiàn)ViewPager頁卡View復(fù)用回收的PagerAdapter,只要是頁面構(gòu)造一樣,則可以使用復(fù)用回收機(jī)制,同時(shí)也支持設(shè)置不同的viewType來實(shí)現(xiàn)多種樣式的頁卡回收復(fù)用,套用RecycleView的Adapter實(shí)現(xiàn)機(jī)制。
要求
- com.android.support:support-v4
- minSdkVersion 9
- 保持跟其他官方支持庫版本一致(如:com.android.support:appcompat-v7)
鏈接
引用
dependencies {
?
compile 'am.util:viewpager:25.3.0'
?
}
提示: 引用最好上Github確認(rèn),有時(shí)項(xiàng)目已更新,但文章未必更新。
使用
整體實(shí)現(xiàn)其實(shí)不難,使用過RecycleView的話,就可以輕車熟路,跟其實(shí)現(xiàn)方案一模一樣。
實(shí)現(xiàn)自己的PagerViewHolder,個(gè)人習(xí)慣在實(shí)例化時(shí)進(jìn)行布局inflate,這樣打開PagerViewHolder便可以直接找到使用的布局文件:
public class MyPagerViewHolder extends RecyclePagerAdapter.PagerViewHolder {
public MyPagerViewHolder(ViewGroup parent) {
super(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_recyclepager_page, parent, false));
}
//應(yīng)用到頁面上的數(shù)據(jù)
public void setData(String data) {
((TextView) itemView).setText(data);
}
}
實(shí)現(xiàn)自己的RecyclePagerAdapter:
public class MyRecyclePagerAdapter extends RecyclePagerAdapter<MyPagerViewHolder> {
private int itemCount = 5;
@Override
public int getItemCount() {
return itemCount;
}
@Override
public MyPagerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//一般同viewType的Holder創(chuàng)建不會超過四個(gè)
return new MyPagerViewHolder(parent);
}
@Override
public void onBindViewHolder(MyPagerViewHolder holder, int position) {
//處理不同頁面的不同數(shù)據(jù)
holder.setData(String.format(Locale.getDefault(),"第%d頁", position + 1));
}
public void add() {
itemCount++;
notifyDataSetChanged();
}
public void remove() {
itemCount--;
itemCount = itemCount < 0 ? 0 : itemCount;
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
//設(shè)置不同類型的頁面。
return 0;
}
@Override
public void onViewRecycled(VH holder) {
//當(dāng)ViewPager執(zhí)行destroyItem時(shí),會回收Holder,此時(shí)會調(diào)用該方法,你可以重寫該方法實(shí)現(xiàn)你要的效果
}
}
原理
ViewPager最多構(gòu)造四個(gè)相同類型的頁面,但是現(xiàn)實(shí)時(shí)最多需要當(dāng)前頁面及左右兩個(gè)頁面,第四個(gè)頁面就可以存起來復(fù)用。
Adapter使用一個(gè)ArrayList<VH>
來存放所有的Holder;再用一個(gè)SparseArray<ArrayList<VH>>
來根據(jù)viewType存放在destroyItem時(shí)候被回收的不同類型的Holder集合,在instantiateItem時(shí)候優(yōu)先從其內(nèi)部獲取,在沒有時(shí)再重新創(chuàng)建。
注意
- notifyDataSetChanged()方法會將所有的未被回收的Holder重新onBindViewHolder一遍,并不是每一個(gè)ViewPager的頁面都會刷新,但當(dāng)前顯示的絕對會刷新;
- notifyItemChanged(int position)用于刷新指定的頁面坐標(biāo)的Holder,只有在這個(gè)頁面處于激活狀態(tài)時(shí),其才會被刷新。