6

アクションバーのドロップダウン ナビゲーションを使用しています。問題は、別のフラグメントに切り替えてから向きを変更すると、savedInstanceState を正しく処理していると思っていても、最初のフラグメントが内部に配置されることです。問題は onNavigationItemSelected が呼び出されるように思われるので、どうすればこれを正しく処理できますか? savedInstanceState 変数をフィールドにすることもできますが、それは間違っているように感じます...

public class MainActivity extends FragmentActivity implements MyListFragment.OnArticleSelectedListener {

public static final String TAG = "MainActivity";

@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(savedInstanceState != null) {
        Fragment savedFragment = getSupportFragmentManager().getFragment(savedInstanceState, "saved_fragment");
        Log.d(MainActivity.TAG, "savedInstanceState != null: " + savedFragment.getTag());

        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fragment_container, savedFragment, savedFragment.getTag())
        .commit();
    } else {

        Log.d(MainActivity.TAG, "savedInstanceState == null");

        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fragment_container, new MyListFragment(), MyListFragment.TAG)
        .commit();
    }

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

    String[] array = new String[] { "Inzeráty", "Dummy frag" };
    SpinnerAdapter mSpinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item,
            array);

    actionBar.setListNavigationCallbacks(mSpinnerAdapter, new ActionBar.OnNavigationListener() {

        @Override
        public boolean onNavigationItemSelected(int itemPosition, long itemId) {

            Log.d(MainActivity.TAG, "onNavitagionItemSelected");

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            switch(itemPosition) {
                case 0: 
                    transaction.replace(R.id.fragment_container, new MyListFragment(), MyListFragment.TAG);
                    break;
                case 1:
                    transaction.replace(R.id.fragment_container, new MyDummyFragment(), MyDummyFragment.TAG);
                    break;
            }
            transaction.commit();
            return true;
        }

    });

}

@Override
public void onArticleSelected(Bundle bundle) {
    Log.d(MainActivity.TAG, "MainActivity # onArticleSelected");
    Intent intent = new Intent(this, DetailActivity.class);
    intent.putExtras(bundle);
    startActivity(intent);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
    Log.d(MainActivity.TAG, "MainActivity # onSaveInstanceState: " + currentFragment.getTag());
    getSupportFragmentManager().putFragment(outState, "saved_fragment", currentFragment);
    super.onSaveInstanceState(outState);
}

}

4

1 に答える 1

2

私も最近この問題に遭遇しました。onRetainCustomNonConfigurationInstanceアクティビティのメソッドをオーバーライドすることで対処しました。

@Override
public Object onRetainCustomNonConfigurationInstance() {
    // return true so that onCreate will know it is an orientation change
    return true;
}

私の中で、onCreate私は以下を実装することができました:

...
Object lastCustomNonConfigurationInstance = getLastCustomNonConfigurationInstance();
if (lastCustomNonConfigurationInstance != null) {
    mIsOrientationChange = (Boolean) getLastCustomNonConfigurationInstance();
}
...

最後に、私onNavigationItemSelectedはそれが知っているように更新しましたmIsOrientationChange

 @Override
public boolean onNavigationItemSelected(int position, long id) {
    if (!mIsOrientationChange) {
        // real navigation selected logic           
    }

    mIsOrientationChange= false;

    return true;
}

編集:次の Android 開発者の記事からこれを実装するというアイデアを得ました: http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject

于 2013-01-16T03:34:06.260 に答える