0

4 ページの ViewPager を使用しています。各ページのフラグメントを効率的に置換/切り替える方法を探しています。

これは私が作成しようとしている相互作用パターンです:

  1. ユーザーが現在フラグメント A を保持しているページでボタンを押す
  2. フラグメント A は、新しいフラグメント B と交換されます
  3. ユーザーはフラグメント B でいくつかの作業を行い、完了したらボタンを押します。
  4. フラグメント B が削除され、フラグメント A (元のフラグメント) に置き換えられます。

これを行う方法を見つけましたが、重大な欠陥があるようです。解決策には、元のフラグメントを削除してからオーバーライドすることが含まれますgetItemPosition(基本的に、この関連する質問で説明されている方法)。

//An array to keep track of the currently visible fragment in each page
private final Fragment[] activeFragments= new Fragment[4];

public void openFragmentB(ViewPager pager, int position) {

    startUpdate(pager);

    //Remove the original fragment
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.remove(activeFragments[position]);
    transaction.commit();

    //Create a new tile search fragment to replace the original fragment
    activeFragments[position] = FragmentB.newInstance();
    pageStates[position] = PageState.STATE_B;

    finishUpdate(pager);
    notifyDataSetChanged();
}

@Override
public int getItemPosition(Object object) {

    //If the main fragment is not active, return POSITION_NONE
    if(object instanceof FragmentA) {
        FragmentA a = (FragmentA) object;
        if(pageStates[a.getPosition()] != PageState.STATE_A) {
            return POSITION_NONE;
        }
    }

    //If the secondary fragment is not active, return POSITION_NONE
    if(object instanceof FragmentB) {
        FragmentB b = (FragmentB) object;
        if(pageStates[b.getPosition()] != PageState.STATE_B) {
            return POSITION_NONE;
        }
    }

    return POSITION_UNCHANGED;
}

この方法は機能しますが、望ましくない副作用があります。フラグメントを削除してその位置を POSITION_NONE に設定すると、フラグメントが破棄されます。したがって、ユーザーが FragmentB の使用を終了したら、元のフラグメントを再利用するのではなく、FragmentA の新しいインスタンスを作成する必要があります。ページャーのメイン フラグメント (この例では FragmentA) には比較的大きなデータベース バック リストが含まれるため、可能であればそれらを再作成することは避けたいと考えています。

基本的に、4 つの主要なフラグメントへの参照を保持し、毎回再作成することなくページ内外でスワップしたいだけです。何か案は?

4

2 に答える 2

1

FragmentPagerAdapter は、getItemIdここで役立つオーバーライド可能なメソッドを提供します。

コレクション内の各 Fragment に一意の long 値を割り当て、このメソッドでそれを返すと、id が変更されたことに気付いたときに、ViewPager が強制的にページをリロードします。

遅刻するよりはましです。これが誰かの役に立てば幸いです。

于 2013-10-22T22:35:54.813 に答える
1

フラグメントの再作成を回避する簡単な方法は、フラグメントをアクティビティのメンバー変数として保持することです。とにかくこれを onRetainCustomNonConfigurationInstance() と組み合わせて実行し、構成の変更中 (主に画面の回転) にフラグメントを保持します。onRetainCustomNonConfigurationInstance は単一のオブジェクトのみを返すため、フラグメントを「保持」オブジェクトに保持します。

あなたの場合、常に Fragment.newInstance() を呼び出す代わりに、新しいオブジェクトを作成する前に、保持オブジェクトに含まれるフラグメントが null かどうかを確認するだけです。null でない場合は、前のインスタンスを再利用します。このチェックは、ViewPager アダプタの getItem(int) メソッドで行う必要があります。

実際には、これを行うことは、基本的に、getItem が呼び出されたときにフラグメントがリサイクルされるかどうかを処理し、getItemPosition(Object) メソッドをオーバーライドして、関連するセグメントに対して常に POSITION_NONE を返すことを意味します。

于 2012-09-26T22:00:54.487 に答える