我目前正在考慮應該使用PagerAdapter的哪個實現。 我已經有兩難困境了。讓我告訴你這些是什麼。FragmentPagerAdapter和FragmentStatePagerAdapter
1#FragmentPagerAdapter
做工精細,它創建片段的新實例時沒有以前的實例可用,並檢索以前的時候有這樣的機會片段。
我已經在計算器上最近讀了,方法PagerAdapter's
getItem()
方法被調用,只有當它需要創建片段,但 - 它被稱爲一遍又一遍,我不得不處理創建新實例和檢索在此方法中的舊身體。
但是 - 只有很少的回調和生命週期方法被調用。例如我不能設法調用onSaveInstanceState
。所以沒有辦法保存片段的狀態 - 當然我可以使用SharedPreferences
或其他東西,但我想使用回調方法。有什麼辦法可以實現嗎?
2#FragmentStatePagerAdapter
完美地工作,節省每次ViewPager
保持片段的狀態。
但 - 這PagerAdapter
總是創建新的片段。我在構造函數中檢查它。
這不是沒有效率嗎?我在Google I/O資料中看到Romain Guy說創建新的Views
效率不高,尤其是當我們在ListView
中創建大量Views
時,所以我們使用convertView
來檢索現有的View
,並根據我們的需要多次更改它。所以頁面之間fliping頗爲類似 - 許多新Views
- 因爲片段是某種View
在這兩個PagerAdapters
我試圖用招重載destroyItem()
方法,但它並沒有在所有的工作。
這是我的問題。
我該怎麼辦?
我是否應該使用SharedPreferences
和選項#1與FragmentPagerAdapter
或選項#2與FragmentStatePagerAdapter
?
是否有任何可能性,我在這些適配器中做了什麼錯誤,他們的行爲不像我們預期的那樣?
下面是我的代碼分爲 「可讀的」 份
PagerAdapter部分#1:
/**
* Adapter class to {@link WizardPager}
*/
public static class WizardCrazyAdapter extends FragmentStatePagerAdapter
implements OnPageChangeListener{
public static final String tag = "android:switcher:"+R.id.pager_w+":";
/**
* Refernece to root activity
*/
WizardActivity wizardActivity;
/**
* list of fragments
*/
private final ArrayList<FragmentInfo> fInfos = new ArrayList<FragmentInfo>();
private short prevPageNumber = 0;
/**
* Constructor of adapter
* @param wizardActivity
* {@link WizardActivity} as reference to activity root
*/
public WizardCrazyAdapter(WizardActivity wizardActivity) {
super(wizardActivity.getSupportFragmentManager());
this.wizardActivity = wizardActivity;
}
static final class FragmentInfo {
private final Class<?> _clss;
private Bundle _args;
public FragmentInfo(Class<?> clss, Bundle args) {
_clss =clss;
_args =args;
}
}
public void addPage(Class<?> clss, Bundle args){
FragmentInfo fi = new FragmentInfo(clss, args);
fInfos.add(fi);
}
/**
* Return number of pages
*/
public int getCount() {
return fInfos.size();
}
PagerAdapter部分#2:
/**
* Searches in {@link FragmentManager} for {@link Fragment} at specified position
* @param position
* @return
*/
private AbstractWizardFragment getFragmentAt(int position){
FragmentManager fm = wizardActivity.getSupportFragmentManager();
AbstractWizardFragment awf = (AbstractWizardFragment) fm.findFragmentByTag(tag+position);
return awf;
}
/**
* Return page of view pager
*/
@Override
public Fragment getItem(int position) {
/*finding existing instance of fragment*/
AbstractWizardFragment awf = getFragmentAt(position);
if(awf == null){
/*creating new instance if no instance exist*/
Log.v("WizardActivity", "creating new Fragment");
FragmentInfo fi = fInfos.get(position);
awf = (AbstractWizardFragment) Fragment.instantiate(wizardActivity, fi._clss.getName());
}else{
Log.v("WizardActivity", "found existing Fragment");
}
return awf;
}
PagerAdapter部分#3:
@Override
public void onPageSelected(int pageNumber) {
wizardActivity.stepFragment.setCurrentStepAndChangeText(pageNumber);
if(pageNumber != prevPageNumber){
AbstractWizardFragment prevFragment = (AbstractWizardFragment) getItem(prevPageNumber);//TODO change if any problems
prevFragment.onDetachedFromViewPager(wizardActivity.mForm);
}
AbstractWizardFragment currFragment = (AbstractWizardFragment) getItem(pageNumber);//TODO change if any problems
currFragment.onAttachedToViewPager(wizardActivity.mForm);
prevPageNumber = (short) pageNumber;
Log.d("WizardActivity", "onPageSelected");
}
@Override
public Object instantiateItem(ViewGroup arg0, int arg1) {
Log.d("WizardActivity", "instantiateItem "+arg1);
return super.instantiateItem(arg0, arg1);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
Log.v("WizardActivity", "that would be destroy");
}
}
Vi ewPager代碼:
public class WizardPager extends ViewPager{
/**
* Flag to check if view pager must be scrolled
*/
protected boolean isScrollable;
/**
* Default constructor
* @param context {@link Context}
*/
public WizardPager(Context context) {
super(context);
isScrollable = true;
}
/**
* Standard constructor
* @param context {@link Context}
* @param attrs {@link AttributeSet}
*/
public WizardPager(Context context, AttributeSet attrs) {
super(context, attrs);
isScrollable = true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.isScrollable) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.isScrollable) {
return super.onInterceptTouchEvent(event);
}
return false;
}
/**
* Enable scroll of pages
*/
public void enableScroll(){
this.isScrollable = true;
}
/**
* Disable scroll of pages
*/
public void disableScroll(){
this.isScrollable = false;
}
/**
* Check if pages can be scrolled
* @return
*/
public boolean isScrollable(){
return isScrollable;
}
}