私は現在、PagerAdapter のどの実装を使用すべきかを考えています。私はそれらの両方に関連するジレンマを持っています。これらが何であるかをお見せしましょう。
1# FragmentPagerAdapter
正常に動作します。以前のインスタンスが利用できない場合はフラグメントの新しいインスタンスを作成し、そのような機会がある場合は以前のフラグメントを取得します。
私は最近 StackOverflow で、メソッドPagerAdapter's
getItem()
method はフラグメントを作成する必要がある場合にのみ呼び出されることを読みましたが、何度も呼び出され、このメソッドの本体内で新しいインスタンスの作成と古いインスタンスの取得を処理する必要がありました。
BUT - コールバック メソッドとライフサイクル メソッドはほとんど呼び出されません。たとえば、私はonSaveInstanceState
呼ばれることができません。したがって、フラグメントの状態を保存する方法はありません-もちろんSharedPreferences
、または他の何かを使用できますが、コールバックメソッドを使用したかったのです。それを達成する方法はありますか?
2# FragmentStatePagerAdapter
完全に機能し、ViewPager
保持するすべてのフラグメントの状態を保存します。
しかし - これPagerAdapter
は常に新しいフラグメントを作成します。コンストラクタ内で確認しました。
非効率じゃないですか?Romain Guy が Google I/O の資料で、新しいものを作成するのは効率的ではないと言っているのをViews
見たことがありViews
ます。したがって、ページ間の切り替えは非常に似ています-多くは新しい-フラグメントはある種のListView
convertView
View
Views
View
どちらもOverriding メソッド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");
}
}
ViewPager コード:
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;
}
}