【问题标题】:Android dynamic Fragment recreated several times on Screen orientation change, after onclick list selectionAndroid动态片段在屏幕方向更改时重新创建了几次,在点击列表选择后
【发布时间】:2014-06-26 21:05:58
【问题描述】:

我正在处理以下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();
}

它为片段 TitlesFragment 修复了它,但是对于片段 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);
  }
}

注意 setRetainInstance(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);
  }
}


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

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

【问题讨论】:

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


    【解决方案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) 方法感兴趣 - 它使片段替换更容易。

    【讨论】:

    • 非常感谢您的提示,但是仅通过标签查找并不能解决问题,请查看我的解决方案以获取详细信息。
    【解决方案2】:

    解决方案:

    this 特定教程中,该问题的解决方案是:

    • 使用 onSaveInstanceStateQuoteFragment 状态存储到其包含的活动中
    • 通过检查是否在 savedInstanceState 中找到 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.

    【讨论】:

      【解决方案3】:

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

      menu.clear()

      在片段内的 onCreateOptionsMenu 方法中膨胀菜单之前

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

      【讨论】:

        猜你喜欢
        • 2013-04-22
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多