簡體   English   中英

選擇onclick列表后,Android動態片段在屏幕方向更改時重新創建了幾次

[英]Android dynamic Fragment recreated several times on Screen orientation change, after onclick list selection

我正在研究以下教程 ,但有問題:每次屏幕旋轉后,它都會重新創建片段。
我通過在QuoteViewerActivity中添加if(savedInstanceState == null)解決TitlesFragment類有關的問題

mFragmentManager = getFragmentManager();
//ADDED THIS CONDITION
if(savedInstanceState == null){
   FragmentTransaction fragmentTransaction = mFragmentManager
                .beginTransaction();
   fragmentTransaction.add(R.id.title_fragment_container, mTitlesFragment);
   fragmentTransaction.commit();
}

它為Fragment TitlesFragment修復了它,但是對於Fragment QuoteFragment,它仍然在每次屏幕方向更改時都重新創建它,因為在本教程中,該片段是在onclick事件中創建的:

@Override
public void onListSelection(int index) {
  if (!mDetailsFragment.isAdded()) {
   FragmentTransaction fragmentTransaction = mFragmentManager
    .beginTransaction();
   fragmentTransaction.add(R.id.quote_fragment_container, mDetailsFragment);
   fragmentTransaction.addToBackStack(null);
   fragmentTransaction.commit();
   mFragmentManager.executePendingTransactions();
  }
  if (mDetailsFragment.getShownIndex() != index) {
     mDetailsFragment.showIndex(index);
  }
}

請注意,在兩個片段的onCreate()中都設置了setRetainInstance(true)

我嘗試添加此檢查,但未解決:

@Override
public void onListSelection(int index) {

  //ADDED THE FOLLOWING TWO LINES
     Fragment f = mFragmentManager.findFragmentById(R.id.quote_fragment_container);
     if(f == null)
  //===============================

  if (!mDetailsFragment.isAdded()) {
   FragmentTransaction fragmentTransaction = mFragmentManager
    .beginTransaction();
   fragmentTransaction.add(R.id.quote_fragment_container, mDetailsFragment);
   fragmentTransaction.addToBackStack(null);
   fragmentTransaction.commit();
   mFragmentManager.executePendingTransactions();
  }
  if (mDetailsFragment.getShownIndex() != index) {
     mDetailsFragment.showIndex(index);
  }
}


==>每當我旋轉屏幕並復制現有菜單時,它都會重新創建此Fragment(在此快照中進行了解釋):

output_snapshot

我在做什么錯,解決此問題的最佳做法是什么? 謝謝!

該行找不到您要查找的片段:

Fragment f = mFragmentManager.findFragmentById(R.id.quote_fragment_container);

您提供了容器(布局)ID。 此方法可用於查找從XML布局放大的片段。

如果要管理代碼中的片段,請使用tag 使用FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)添加一個片段。 提供一個tag您以后可以使用FragmentManager.findFragmentByTag(String tag)找到該片段。 使tag具有某種static final String常量是一個好主意,從而使自動重構變得輕而易舉。

您可能還對FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)方法感興趣-它使片段替換更加容易。

解:

特定教程中,通過以下方法解決了該問題的解決方案:

  • 使用onSaveInstanceStateQuoteFragment狀態存儲到其包含的活動
  • 通過檢查是否在savedInstanceState中找到QuoteFragment來獲取/處理QuoteFragment

這是我在代碼中添加/更改的內容:

.....
private  QuoteFragment mDetailsFragment = new QuoteFragment();//REMOVED final attribute
......

//ADDED
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    if(mFragmentManager.findFragmentByTag(quote_fragment_tag)!=null)
        getFragmentManager().putFragment(outState, QuoteFragment.class.getName(), mDetailsFragment);
}

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TitleArray = getResources().getStringArray(R.array.Titles);
    QuoteArray = getResources().getStringArray(R.array.Quotes);
    setContentView(R.layout.main);

    mFragmentManager = getFragmentManager();

    // ADDED
    if(savedInstanceState == null){
        FragmentTransaction fragmentTransaction = mFragmentManager
                .beginTransaction();
        fragmentTransaction.add(R.id.title_fragment_container, mTitlesFragment);
        fragmentTransaction.commit();

    }
    else{//ADDED
        mDetailsFragment = (QuoteFragment) getFragmentManager()
                .getFragment(savedInstanceState, QuoteFragment.class.getName());
       if(mDetailsFragment == null){
            mDetailsFragment = new QuoteFragment();
            mFragmentManager.beginTransaction()
            .add(R.id.quote_fragment_container, mDetailsFragment,quote_fragment_tag)
            .addToBackStack(null)
            .commit();  
            mFragmentManager.executePendingTransactions();
       }
       }
}

注意:

以我的拙見 ,關於片段和運行時更改配置的最佳實踐,請查看Google的官方教程。

另一個簡單的解決方案。添加

menu.clear()

在片段內的onCreateOptionsMenu方法中放大菜單之前

 @Override
    public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.menu_main, menu);


    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM