1

アクションバーのタブとして複数のフラグメントを含むアプリケーションを作成しています。タブを切り替えてアプリケーションを閉じる間、これらのフラグメントのプロセスを実行し続ける必要があります(アプリケーションを終了するのではなく、ホームまたは戻るを押したときに、アプリケーションをバックグラウンドで実行し続けたい)。そのため、タブを切り替えながらフラグメントを実行し続けるために、SDKのサンプルTabListenerの1つを変更して、アタッチとデタッチではなく表示と非表示を設定しました。そのためのコードは次のとおりです。

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;
    private final Bundle mArgs;


    public TabListener(Activity activity, String tag, Class<T> clz) {
        this(activity, tag, clz, null);
    }

    public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
        mArgs = args;

        // Check to see if we already have a fragment for this tab, probably
        // from a previously saved state.  If so, deactivate it, because our
        // initial state is that a tab isn't shown.
        mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
        if (mFragment != null && !mFragment.isHidden()) {
            FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
            ft.hide(mFragment);
            ft.commit();
        }
    }

    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            ft.show(mFragment);
        }
    }

    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.hide(mFragment);
        }
    }

    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

そして、タブは次のように作成されます。

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    ActionBar.Tab aTab= actionBar.newTab().setText("Tab A").setTabListener(new TabListener<AFragment>(this, "AFrag", AFragment.class));
    actionBar.addTab(aTab);
    ActionBar.Tab bTab= actionBar.newTab().setText("Tab B").setTabListener(new TabListener<BFragment>(this, "BFrag", BFragment.class));
    actionBar.addTab(bTab);

したがって、少なくともタブを切り替えるために、これは機能するようです。ただし、TabListenerの実装が異なる場合はフラグメントが重なり合って表示されることがあり、それ以降は発生していないため、現在は表示されていない可能性があります。なぜ発生したのかわからないので、どうやって複製できるのかわかりません。

ただし、アプリを閉じるときはかなりバグがあります。ほとんどの場合、ホームを押すと、アプリは引き続き機能し、再度開いたときに実行されます。時々それはそうではありません、それは奇妙です。押し戻すとアプリケーションも閉じますが、再度起動するとアプリケーションが最初から再起動するように見えますが、これは望ましくありません。それから押し戻すと、以前に実行されていたフラグメントに戻ることがあります。

しかし、それはかなりランダムで不安定です。いつ機能するかは予測できません。安定性を向上させて、閉じたときに実行を継続し、アプリケーションを再度開いても再起動しないようにするための最善の方法は何ですか?

4

2 に答える 2

0

を使用して Fragment を維持することもできますがFragment.setRetainInstance(true)、これは向きの変更に対してのみ機能する可能性がありますが、ドキュメントは少し不明確です。

Fragmentを保持する方法が私が知っている方法がないことに失敗しました。おそらく、保持したいすべてを の Bundle オブジェクトに保存し、このデータを または のいずれかFragment.onSaveInstanceState(..)で読み取るのが最善の策でしょう。Fragment.onCreate(..)Fragment.onCreateView(..)

私がよく知らない別の方法は、Fragment.SavedStateクラスを使用することです。これは、状態をいつでも手動で保存できることを除いて、上記と似ているようです。これにはかなりのコーディングが必要になりますが、より細かく制御できます。

于 2012-08-26T10:44:15.813 に答える
0

アクティビティと同様に、フラグメントはその状態をバンドルに保存でき、onCreate()呼び出されたときに渡されます。アプリが(メモリのために)強制終了された場合でも、状態を保存して復元できるようにすることができます。

また、使用をお勧めします

ft.addToBackStack(null)
    .remove(CurrentFragment)
    .add(ToShowFragment)
    .commit()

を使用しpopBackStack()て、フラグメントの追加と削除を簡単に処理できるようにします。replace()また、適切に反転されていないため、バックスタックからのポップでは機能しないことに注意してください (状態例外が発生します)。

于 2012-08-26T01:54:35.633 に答える