6

我有一个操作栏下拉导航。问题是,当我切换到不同的片段,然后进行方向更改时,它将第一个片段放在里面,尽管我认为我正确地处理了savedInstanceState。问题似乎是onNavigationItemSelected被调用,所以......我将如何正确处理这个问题?我可以使savedInstanceState变量场,但只是觉得不妥......ActionBar下拉导航 - 方向更改放入错误的片段

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); 
} 

}

回答

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

+0

嗨,我实际上最终做的是坚持保存的实例 – urSus

+0

下拉列表中选择的项目索引(实际上,我将索引存储为SharedPreference,以便它可以在启动应用程序时使用,如果它后来打开时不再在内存中运行)。我面临的问题有点不同,因为可见片段可能会启动另一个子片段。在轮换时,它会返回到父代片段而不是孩子,上面的代码允许我解决第二个问题。 –

+0

这会导致在操作栏的下拉菜单中显示错误的片段。 – howettl