Android multiple fragment transaction ordering

前端 未结 5 1770
离开以前
离开以前 2020-12-09 05:10

I have a HorizontalScrollView containing a (horizontal) LinearLayout which I use as the container for adding multiple fragments. Upon some changes,

5条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-09 05:50

    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}
    

    And here is the culprit code:

    http://grepcode.com/file/repository.grepcode.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();
                }
                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);
        }
    

    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...

    EDIT:

    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();
    

    Where FragmentTransactionBugFixHack looks like this:

    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.

提交回复
热议问题