Android的多个片段事务排序 [英] Android multiple fragment transaction ordering

查看:266
本文介绍了Android的多个片段事务排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Horizo​​ntalScrollView 含(水平)的LinearLayout 这是我作为容器添加多个片段使用。当一些变化,我需要删除该容器中的所有片段,并添加新的。然而,似乎与当我删除旧的片段排序的问题。

I have a HorizontalScrollView containing a (horizontal) LinearLayout which I use as the container for adding multiple fragments. Upon some changes, I need to remove all fragments from that container and add new ones. However, there seems to be a problem with ordering when I'm removing the old fragments.

下面是情景:

  • 在应用程序启动时
    • 在正确添加片段 A1 B1 C1 D 1 这个顺序
    • app startup
      • correctly adding fragments A1,B1,C1,D1 in this order
      • 如果不删除初始片段,但添加 A2 B2 C2 (作为一个单一的交易),它会显示<$c$c>A1,<$c$c>B1,<$c$c>C1,<$c$c>D1,<$c$c>A2,<$c$c>B2,<$c$c>C2
      • 如果除去初始片段(无论是作为一个独立的或使用相同的事务),然后加入 A2 B2 C2 ,就会显示 C2 B2 A2
      • if not removing initial fragments, but adding A2,B2,C2 (as a single transaction), it will show A1,B1,C1,D1,A2,B2,C2
      • if removing initial fragments (either as a separate or using the same transaction), then adding A2,B2,C2, it will show C2,B2,A2

      现在我找到了一个解决办法,在那里我第一次加入新片段,然后取出旧的(还是作为同一事务的一部分),并且工作正常。

      For now I found a workaround, where I'm adding the new fragments first then removing the old ones (still as part of the same transaction) and that is working properly.

      编辑:的变通方法不起作用所有的时间

      The workaround doesn't work all the time.

      我用 android.support.v4.app.Fragment

      这是发生了什么任何想法?

      Any ideas on what's happening?

      推荐答案

      我启用调试的FragmentManager,我发现这个问题。

      I enabled debugging on the FragmentManager and I found the problem.

      下面是从日志的摘录,请注意碎片索引分配以相反的顺序:

      Here's an excerpt from the logs, notice how the fragment index is allocated in reverse order:

      V/FragmentManager? Freeing fragment index TimeTracesChartFragment{42ac4910 #7 id=0x7f080044}
      V/FragmentManager? add: RealTimeValuesFragment{42a567b0 id=0x7f080044}
      V/FragmentManager? Allocated fragment index RealTimeValuesFragment{42a567b0 #7 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d35c38 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d35c38 #6 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d35e98 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d35e98 #5 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d36220 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d36220 #4 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d39d18 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d39d18 #3 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d3a170 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d3a170 #2 id=0x7f080044}
      V/FragmentManager? add: TimeTracesChartFragment{42d3a528 id=0x7f080044}
      V/FragmentManager? Allocated fragment index TimeTracesChartFragment{42d3a528 #1 id=0x7f080044}
      V/FragmentManager? moveto CREATED: TimeTracesChartFragment{42d3a528 #1 id=0x7f080044}
      

      这里是罪魁祸首code:

      And here is the culprit code:

      <一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/app/FragmentManager.java#FragmentManagerImpl.makeActive%28android.support.v4.app.Fragment%29" rel="nofollow">http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/app/FragmentManager.java#FragmentManagerImpl.makeActive%28android.support.v4.app.Fragment%29

       void makeActive(Fragment f) {
              if (f.mIndex >= 0) {
                  return;
              }
      
              if (mAvailIndices == null || mAvailIndices.size() <= 0) {
                  if (mActive == null) {
                      mActive = new ArrayList<Fragment>();
                  }
                  f.setIndex(mActive.size(), mParent);
                  mActive.add(f);
      
              } else {
                  f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
                  mActive.set(f.mIndex, f);
              }
              if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
          }
      

      注意,可用指数如何从列表的后服用。它可能应该选择指数最低可用,以便将preserve排序。

      Notice how the available indices are taken from the back of the list. It should probably choose the lowest index available so that it would preserve ordering.

      现在想出一个变通办法的......

      Now to think of a workaround...

      编辑:

      下面是一个解决办法: 创建两个单独的事务,一个用于清除,然后一个用于添加,那么这样做:

      Here's a workaround: Create two separate transactions, one for the removals and then one for the additions, then do this:

      removalTxn.commit();
      getSupportFragmentManager().executePendingTransactions();
      FragmentTransactionBugFixHack.reorderIndices(getSupportFragmentManager());
      //create additionTxn
      additionTxn.commit();
      

      其中, FragmentTransactionBugFixHack 是这样的:

      package android.support.v4.app;
      
      import java.util.Collections;
      
      public class FragmentTransactionBugFixHack {
      
          public static void reorderIndices(FragmentManager fragmentManager) {
              if (!(fragmentManager instanceof FragmentManagerImpl))
                  return;
              FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
              if (fragmentManagerImpl.mAvailIndices != null)
                  Collections.sort(fragmentManagerImpl.mAvailIndices, Collections.reverseOrder());
          }
      
      }
      

      这不是理想的,两个独立的交易,因为它会闪烁白色(或任何你的容器的背景),但至少它会责令其正常工作。

      It's not ideal, because of the two separate transaction it will flicker to white (or whatever your container's background is), but at least it will order them properly.

      这篇关于Android的多个片段事务排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆