29
29
import android .view .ViewGroup ;
30
30
import android .view .ViewParent ;
31
31
import android .widget .FrameLayout ;
32
+
32
33
import androidx .annotation .CallSuper ;
33
34
import androidx .annotation .NonNull ;
34
35
import androidx .annotation .Nullable ;
47
48
import androidx .viewpager2 .adapter .StatefulAdapter ;
48
49
import androidx .viewpager2 .widget .ViewPager2 ;
49
50
50
- import com .duckduckgo .common .ui .tabs .SwipingTabsFeatureProvider ;
51
51
import com .duckduckgo .app .browser .tabs .TabManager ;
52
+ import com .duckduckgo .common .ui .tabs .SwipingTabsFeatureProvider ;
52
53
53
54
import java .util .ArrayDeque ;
54
55
import java .util .ArrayList ;
57
58
import java .util .Set ;
58
59
import java .util .concurrent .ConcurrentHashMap ;
59
60
import java .util .concurrent .CopyOnWriteArrayList ;
61
+
60
62
import timber .log .Timber ;
61
63
62
64
/**
@@ -89,7 +91,6 @@ public abstract class FragmentStateAdapter extends RecyclerView.Adapter<Fragment
89
91
implements StatefulAdapter {
90
92
// State saving config
91
93
private static final String KEY_PREFIX_FRAGMENT = "f#" ;
92
- private static final String KEY_PREFIX_STATE = "s#" ;
93
94
94
95
// Fragment GC config
95
96
private static final long GRACE_WINDOW_TIME_MS = 10_000 ; // 10 seconds
@@ -107,7 +108,6 @@ public abstract class FragmentStateAdapter extends RecyclerView.Adapter<Fragment
107
108
@ SuppressWarnings ("WeakerAccess" ) // to avoid creation of a synthetic accessor
108
109
final LongSparseArray <Fragment > mFragments = new LongSparseArray <>();
109
110
110
- private final LongSparseArray <Fragment .SavedState > mSavedStates = new LongSparseArray <>();
111
111
private final LongSparseArray <Integer > mItemIdToViewHolder = new LongSparseArray <>();
112
112
113
113
private FragmentMaxLifecycleEnforcer mFragmentMaxLifecycleEnforcer ;
@@ -130,42 +130,20 @@ public abstract class FragmentStateAdapter extends RecyclerView.Adapter<Fragment
130
130
/**
131
131
* @param fragmentActivity if the {@link ViewPager2} lives directly in a {@link
132
132
* FragmentActivity} subclass.
133
- * @see FragmentStateAdapter#FragmentStateAdapter(Fragment)
134
- * @see FragmentStateAdapter#FragmentStateAdapter(FragmentManager, Lifecycle)
135
- */
136
- public FragmentStateAdapter (@ NonNull FragmentActivity fragmentActivity ) {
137
- this (fragmentActivity .getSupportFragmentManager (), fragmentActivity .getLifecycle ());
138
- }
139
-
140
- /**
141
- * @param fragment if the {@link ViewPager2} lives directly in a {@link Fragment} subclass.
142
- * @see FragmentStateAdapter#FragmentStateAdapter(FragmentActivity)
143
- * @see FragmentStateAdapter#FragmentStateAdapter(FragmentManager, Lifecycle)
144
- */
145
- public FragmentStateAdapter (@ NonNull Fragment fragment ) {
146
- this (fragment .getChildFragmentManager (), fragment .getLifecycle ());
147
- }
148
-
149
- /**
150
- * @param fragmentManager of {@link ViewPager2}'s host
151
- * @param lifecycle of {@link ViewPager2}'s host
152
- * @see FragmentStateAdapter#FragmentStateAdapter(FragmentActivity)
153
- * @see FragmentStateAdapter#FragmentStateAdapter(Fragment)
133
+ * @param swipingTabsFeature Feature flag to enable swiping tabs fixes
154
134
*/
155
135
public FragmentStateAdapter (
156
- @ NonNull FragmentManager fragmentManager , @ NonNull Lifecycle lifecycle ) {
157
- mFragmentManager = fragmentManager ;
158
- mLifecycle = lifecycle ;
159
- mSwipingTabsFeature = null ;
160
- super . setHasStableIds ( true );
136
+ @ NonNull FragmentActivity fragmentActivity ,
137
+ SwipingTabsFeatureProvider swipingTabsFeature ) {
138
+ this ( fragmentActivity . getSupportFragmentManager (),
139
+ fragmentActivity . getLifecycle (),
140
+ swipingTabsFeature );
161
141
}
162
142
163
143
/**
164
144
* @param fragmentManager of {@link ViewPager2}'s host
165
145
* @param lifecycle of {@link ViewPager2}'s host
166
146
* @param swipingTabsFeature Feature flag to enable swiping tabs fixes
167
- * @see FragmentStateAdapter#FragmentStateAdapter(FragmentActivity)
168
- * @see FragmentStateAdapter#FragmentStateAdapter(Fragment)
169
147
*/
170
148
public FragmentStateAdapter (
171
149
@ NonNull FragmentManager fragmentManager ,
@@ -307,7 +285,6 @@ private void ensureFragment(int position) {
307
285
if (!mFragments .containsKey (itemId )) {
308
286
// TODO(133419201): check if a Fragment provided here is a new Fragment
309
287
Fragment newFragment = createFragment (position );
310
- newFragment .setInitialSavedState (mSavedStates .get (itemId ));
311
288
mFragments .put (itemId , newFragment );
312
289
}
313
290
}
@@ -519,10 +496,6 @@ private void removeFragment(long itemId) {
519
496
}
520
497
}
521
498
522
- if (!containsItem (itemId )) {
523
- mSavedStates .remove (itemId );
524
- }
525
-
526
499
if (!fragment .isAdded ()) {
527
500
mFragments .remove (itemId );
528
501
return ;
@@ -538,8 +511,6 @@ private void removeFragment(long itemId) {
538
511
mFragmentEventDispatcher .dispatchPreSavedInstanceState (fragment );
539
512
Fragment .SavedState savedState = mFragmentManager .saveFragmentInstanceState (fragment );
540
513
mFragmentEventDispatcher .dispatchPostEvents (onPost );
541
-
542
- mSavedStates .put (itemId , savedState );
543
514
}
544
515
List <FragmentTransactionCallback .OnPostEventListener > onPost =
545
516
mFragmentEventDispatcher .dispatchPreRemoved (fragment );
@@ -635,7 +606,7 @@ public final void setHasStableIds(boolean hasStableIds) {
635
606
@ Override
636
607
public final @ NonNull Parcelable saveState () {
637
608
/* TODO(b/122670461): use custom {@link Parcelable} instead of Bundle to save space */
638
- Bundle savedState = new Bundle (mFragments .size () + mSavedStates . size () );
609
+ Bundle savedState = new Bundle (mFragments .size ());
639
610
640
611
/* save references to active fragments */
641
612
for (int ix = 0 ; ix < mFragments .size (); ix ++) {
@@ -646,23 +617,13 @@ public final void setHasStableIds(boolean hasStableIds) {
646
617
mFragmentManager .putFragment (savedState , key , fragment );
647
618
}
648
619
}
649
-
650
- /* Write {@link mSavedStates) into a {@link Parcelable} */
651
- for (int ix = 0 ; ix < mSavedStates .size (); ix ++) {
652
- long itemId = mSavedStates .keyAt (ix );
653
- if (containsItem (itemId )) {
654
- String key = createKey (KEY_PREFIX_STATE , itemId );
655
- savedState .putParcelable (key , mSavedStates .get (itemId ));
656
- }
657
- }
658
-
659
620
return savedState ;
660
621
}
661
622
662
623
@ Override
663
624
@ SuppressWarnings ("deprecation" )
664
625
public final void restoreState (@ NonNull Parcelable savedState ) {
665
- if (!mSavedStates . isEmpty () || ! mFragments .isEmpty ()) {
626
+ if (!mFragments .isEmpty ()) {
666
627
throw new IllegalStateException (
667
628
"Expected the adapter to be 'fresh' while restoring state." );
668
629
}
@@ -676,21 +637,14 @@ public final void restoreState(@NonNull Parcelable savedState) {
676
637
for (String key : bundle .keySet ()) {
677
638
if (isValidKey (key , KEY_PREFIX_FRAGMENT )) {
678
639
long itemId = parseIdFromKey (key , KEY_PREFIX_FRAGMENT );
679
- Fragment fragment = mFragmentManager .getFragment (bundle , key );
680
- mFragments .put (itemId , fragment );
681
- continue ;
682
- }
683
-
684
- if (isValidKey (key , KEY_PREFIX_STATE )) {
685
- long itemId = parseIdFromKey (key , KEY_PREFIX_STATE );
686
- Fragment .SavedState state = bundle .getParcelable (key );
687
- if (containsItem (itemId )) {
688
- mSavedStates .put (itemId , state );
640
+ try {
641
+ Fragment fragment = mFragmentManager .getFragment (bundle , key );
642
+ mFragments .put (itemId , fragment );
643
+ } catch (IllegalStateException e ) {
644
+ Timber .w ("FragmentManager is in a bad state, unable to restore fragment %d" ,
645
+ itemId );
689
646
}
690
- continue ;
691
647
}
692
-
693
- throw new IllegalArgumentException ("Unexpected key in savedState: " + key );
694
648
}
695
649
696
650
if (!mFragments .isEmpty ()) {
0 commit comments