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