在onclick列表选择之后,Android动态片段在屏幕方向更改上重新创建了几次

时间:2014-06-26 21:05:59

标签: android android-fragments screen-orientation android-listfragment

我正在处理以下tutorial,它有问题:它会在每次屏幕旋转后重新创建片段。
我通过在 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);
  }
}

请注意,setCetainInstance(true)在两个片段中都设置了onCreate()

我尝试添加此检查,但它没有修复它:

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


==>每次旋转屏幕并复制现有菜单时,它都会重新创建此片段(在此快照中说明):

output_snapshot

我做错了什么,解决这个问题的最佳做法是什么?谢谢!

3 个答案:

答案 0 :(得分:1)

此行无法找到您尝试查找的片段:

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)感兴趣 - 它使片段替换更容易。

答案 1 :(得分:0)

解决方案:

特定教程中,此问题的解决方案通过以下方式解决:

  • 使用 onSaveInstanceState QuoteFragment 状态存储到其包含的活动中
  • 通过检查 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's official tutorial.

答案 2 :(得分:0)

另一个简单的解决方案。添加

  

menu.clear()

在片段

中的onCreateOptionsMenu方法中膨胀菜单之前
 @Override
    public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.menu_main, menu);


    }