ActionBar下拉导航 - 屏幕方向改变后,错误的片段出现了。

6

我正在使用actionbar下拉导航。问题是,当我切换到不同的片段,然后进行方向更改时,它仍会在内部放置第一个片段,即使我认为我正确处理了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);
}

}

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


嗨,我最终实际上所做的是将下拉列表中所选项目的索引持久化保存在savedinstance中。 - urSus
我也在这样做(实际上,我将索引存储为SharedPreference,以便在稍后重新打开应用程序时使用,而不再运行在内存中)。我面临的问题有点不同,即可见片段可能会启动另一个子片段。旋转后,它将返回到父片段而不是子片段,上面的代码允许我解决第二个问题。 - Mike Schreiner
这会导致在操作栏的下拉菜单中显示错误的片段。 - howettl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接