From b874d255635ee6cff93447d2da105cc355631476 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 31 Jan 2017 19:46:51 -0800 Subject: [PATCH] fix iterating over fragments Old code that didn't rotate properly was meant to associate view IDs with fragments so I could iterate over them, e.g. to dispatch intents. To replace that the common superclass of all fragments now keeps a set of active ones and provides a method that uses that to find the fragment that owns a view. So I can iterate over fragments based on the dualcontainer-contained views as before. --- .../org/eehouse/android/xw4/MainActivity.java | 34 ++++++++++--------- .../org/eehouse/android/xw4/XWFragment.java | 24 +++++++++++++ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java index 9aa9e6eab..b413809ef 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MainActivity.java @@ -148,7 +148,7 @@ public class MainActivity extends XWActivity break; } View child = m_root.getChildAt( top ); - XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() ); + XWFragment frag = findFragment( child ); if ( frag == newTopFrag ) { break; } @@ -168,11 +168,10 @@ public class MainActivity extends XWActivity private boolean dispatchNewIntentImpl( Intent intent ) { boolean handled = false; - FragmentManager fm = getSupportFragmentManager(); for ( int ii = m_root.getChildCount() - 1; !handled && ii >= 0; --ii ) { View child = m_root.getChildAt( ii ); - XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() ); + XWFragment frag = findFragment( child ); if ( null != frag ) { handled = frag.getDelegate().canHandleNewIntent( intent ); if ( handled ) { @@ -260,7 +259,8 @@ public class MainActivity extends XWActivity public int m_request; public int m_result; public Intent m_data; - public PendingResultCache( Fragment target, int request, int result, Intent data ) { + public PendingResultCache( Fragment target, int request, + int result, Intent data ) { m_frag = new WeakReference(target); m_request = request; m_result = result; @@ -343,8 +343,7 @@ public class MainActivity extends XWActivity XWFragment frag = null; View child = m_root.getChildAt( m_root.getChildCount() - 1 ); if ( null != child ) { - frag = (XWFragment)getSupportFragmentManager() - .findFragmentById( child.getId() ); + frag = findFragment( child ); } return frag; } @@ -356,8 +355,7 @@ public class MainActivity extends XWActivity XWFragment[] result = new XWFragment[count]; for ( int ii = 0; ii < count; ++ii ) { View child = m_root.getChildAt( childCount - 1 - ii ); - result[ii] = (XWFragment)getSupportFragmentManager() - .findFragmentById( child.getId() ); + result[ii] = findFragment( child ); } return result; @@ -395,26 +393,30 @@ public class MainActivity extends XWActivity private void trySetTitle( View view ) { - XWFragment frag = (XWFragment) - getSupportFragmentManager().findFragmentById( view.getId() ); + XWFragment frag = findFragment( view ); if ( null != frag ) { frag.setTitle(); } else { - DbgUtils.logd( TAG, "trySetTitle(): no fragment for id %x", - view.getId() ); + DbgUtils.logd( TAG, "trySetTitle(): no fragment found" ); } } private void setMenuVisibility( View cont, boolean visible ) { - FragmentManager fm = getSupportFragmentManager(); - int hidingId = cont.getId(); - Fragment frag = fm.findFragmentById( hidingId ); + Fragment frag = findFragment( cont ); if ( null != frag ) { // hasn't been popped? frag.setMenuVisibility( visible ); } } + private XWFragment findFragment( View view ) + { + XWFragment frag = XWFragment.findOwnsView( view ); + DbgUtils.logd( TAG, "findFragmentById(view=%s) => " + frag, + view.toString() ); + return frag; + } + private void addFragmentImpl( Fragment fragment, Bundle bundle, String parentName ) { @@ -471,7 +473,7 @@ public class MainActivity extends XWActivity popUnneeded( fm, newName, parentName ); fm.beginTransaction() - .add( R.id.main_container, fragment ) + .add( R.id.main_container, fragment, newName ) .addToBackStack( newName ) .commit(); // Don't do this. It causes an exception if e.g. from fragment.start() diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java index 5dce96b1e..feb095c42 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWFragment.java @@ -33,6 +33,9 @@ import android.view.ViewGroup; import android.widget.ListAdapter; import android.widget.ListView; +import java.util.HashSet; +import java.util.Set; + import junit.framework.Assert; abstract class XWFragment extends Fragment implements Delegator { @@ -43,6 +46,25 @@ abstract class XWFragment extends Fragment implements Delegator { private String m_parentName; private boolean m_hasOptionsMenu = false; + private static Set sActiveFrags = new HashSet(); + public static XWFragment findOwnsView( View view ) + { + XWFragment result = null; + DbgUtils.assertOnUIThread(); + for ( XWFragment frag : sActiveFrags ) { + DbgUtils.logd( TAG, "findOwnsView(): looking at fragment %s", + frag.getClass().getSimpleName() ); + if ( frag.getView() == view ) { + Assert.assertNull( result ); + result = frag; + // break; + } + } + + DbgUtils.logd( TAG, "findOwnsView() => " + result ); + return result; + } + public XWFragment setParentName( Delegator parent ) { m_parentName = null == parent ? "" @@ -99,6 +121,7 @@ abstract class XWFragment extends Fragment implements Delegator { Bundle savedInstanceState ) { DbgUtils.logd( TAG, "%s.onCreateView() called", getClass().getSimpleName() ); + sActiveFrags.add(this); return m_dlgt.inflateView( inflater, container ); } @@ -150,6 +173,7 @@ abstract class XWFragment extends Fragment implements Delegator { { DbgUtils.logd( TAG, "%s.onDestroy() called", getClass().getSimpleName() ); m_dlgt.onDestroy(); + sActiveFrags.remove( this ); super.onDestroy(); }