- 好比,引導頁使用ViewPager,這個時候動態管理的Adapter,能夠每次都會建立新view,銷燬舊View。節省內存消耗性能。能夠說下面這種用的最多……
/**
* <pre>
* @author yangchong
* blog : https://github.com/yangchong211
* time : 2016/3/18
* desc : 動態管理的Adapter。概念參照{@link android.support.v4.app.FragmentPagerAdapter}
* 每次都會建立新view,銷燬舊View。節省內存消耗性能
* revise: 好比使用場景是啓動引導頁
* </pre>
*/
public abstract class AbsDynamicPagerAdapter extends PagerAdapter {
@Override
public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
return arg0==arg1;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
@Override
public int getItemPosition(@NonNull Object object) {
return super.getItemPosition(object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View itemView = getView(container,position);
container.addView(itemView);
return itemView;
}
/**
* 建立view
* @param container container
* @param position 索引
* @return
*/
public abstract View getView(ViewGroup container, int position);
}
複製代碼
- 好比,常見有無限輪播圖,能夠自動輪播,你們應該用的特別多。這個時候能夠優化自定義輪播圖的PagerAdapter,建立集合用來存儲view,再次用的時候先取集合,沒有就建立。而不是頻繁建立視圖。
/**
* <pre>
* @author yangchong
* blog : https://github.com/yangchong211
* time : 2016/3/18
* desc : AbsLoopPagerAdapter
* revise: 若是是自動輪播圖的話就用這一個
* </pre>
*/
public abstract class AbsLoopPagerAdapter extends PagerAdapter {
private BannerView mViewPager;
/**
* 用來存放View的集合
*/
private ArrayList<View> mViewList = new ArrayList<>();
/**
* 刷新所有
*/
@Override
public void notifyDataSetChanged() {
mViewList.clear();
initPosition();
super.notifyDataSetChanged();
}
/**
* 獲取item索引
*
* POSITION_UNCHANGED表示位置沒有變化,即在添加或移除一頁或多頁以後該位置的頁面保持不變,
* 能夠用於一個ViewPager中最後幾頁的添加或移除時,保持前幾頁仍然不變;
*
* POSITION_NONE,表示當前頁再也不做爲ViewPager的一頁數據,將被銷燬,能夠用於無視View緩存的刷新;
* 根據傳過來的參數Object來判斷這個key所指定的新的位置
* @param object objcet
* @return
*/
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
/**
* 註冊數據觀察者監聽
* @param observer observer
*/
@Override
public void registerDataSetObserver(@NonNull DataSetObserver observer) {
super.registerDataSetObserver(observer);
initPosition();
}
private void initPosition(){
if (getRealCount()>1){
if (mViewPager.getViewPager().getCurrentItem() == 0&&getRealCount()>0){
int half = Integer.MAX_VALUE/2;
int start = half - half%getRealCount();
setCurrent(start);
}
}
}
/**
* 設置位置,利用反射實現
* @param index 索引
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private void setCurrent(int index){
try {
Field field = ViewPager.class.getDeclaredField("mCurItem");
field.setAccessible(true);
field.set(mViewPager.getViewPager(),index);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
public AbsLoopPagerAdapter(BannerView viewPager){
this.mViewPager = viewPager;
}
@Override
public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
return arg0==arg1;
}
/**
* 若是頁面不是當前顯示的頁面也不是要緩存的頁面,會調用這個方法,將頁面銷燬。
* @param container container
* @param position 索引
* @param object object
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
Log.d("PagerAdapter","銷燬的方法");
}
/**
* 要顯示的頁面或須要緩存的頁面,會調用這個方法進行佈局的初始化。
* @param container container
* @param position 索引
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int realPosition = position%getRealCount();
View itemView = findViewByPosition(container,realPosition);
container.addView(itemView);
Log.d("PagerAdapter","建立的方法");
return itemView;
}
/**
* 這個是避免重複建立,若是集合中有,則取集合中的
* @param container container
* @param position 索引
* @return
*/
private View findViewByPosition(ViewGroup container, int position){
for (View view : mViewList) {
if (((int)view.getTag()) == position&&view.getParent()==null){
return view;
}
}
View view = getView(container,position);
view.setTag(position);
mViewList.add(view);
return view;
}
@Deprecated
@Override
public final int getCount() {
//設置最大輪播圖數量 ,若是是1那麼就是1,不輪播;若是大於1則設置一個最大值,能夠輪播
//return getRealCount();
return getRealCount()<=1?getRealCount(): Integer.MAX_VALUE;
}
/**
* 獲取輪播圖數量
* @return 數量
*/
public abstract int getRealCount();
/**
* 建立view
* @param container viewGroup
* @param position 索引
* @return
*/
public abstract View getView(ViewGroup container, int position);
}
複製代碼
- 還有一種場景,靜態輪播圖,也就是不會自動輪播,可是手指能夠滑動,而且滑動到第一張不能往左滑動,滑動到最後一張不能向右滑動。這種場景,view添加進去就無論了,View就常在呢!
/**
* <pre>
* @author yangchong
* blog : https://github.com/yangchong211
* time : 2016/3/18
* desc : 靜態存儲的Adapter,概念參照{@link android.support.v4.app.FragmentStatePagerAdapter}
* view添加進去就無論了,View長在,內存再也不
* revise: 若是是靜態輪播圖就用這個
* </pre>
*/
public abstract class AbsStaticPagerAdapter extends PagerAdapter {
private ArrayList<View> mViewList = new ArrayList<>();
@Override
public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
return arg0==arg1;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
Log.d("PagerAdapter","銷燬的方法");
}
@Override
public void notifyDataSetChanged() {
mViewList.clear();
super.notifyDataSetChanged();
}
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View itemView = findViewByPosition(container,position);
container.addView(itemView);
onBind(itemView,position);
Log.d("PagerAdapter","建立的方法");
return itemView;
}
private View findViewByPosition(ViewGroup container, int position){
for (View view : mViewList) {
if (((int)view.getTag()) == position&&view.getParent()==null){
return view;
}
}
View view = getView(container,position);
view.setTag(position);
mViewList.add(view);
return view;
}
public void onBind(View view, int position){}
public abstract View getView(ViewGroup container, int position);
}
複製代碼
- 這三種不一樣的使用場景,咱們應該都見到過,那麼自定義adpater的時候可否再優化一下,ok,上面的方案恰好合適。若是有不一樣的想法,歡迎提出……該源代碼的開源地址:github.com/yangchong21…