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.
This commit is contained in:
Eric House 2017-01-31 19:46:51 -08:00
parent 0fedcf56ab
commit b874d25563
2 changed files with 42 additions and 16 deletions

View file

@ -148,7 +148,7 @@ public class MainActivity extends XWActivity
break; break;
} }
View child = m_root.getChildAt( top ); View child = m_root.getChildAt( top );
XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() ); XWFragment frag = findFragment( child );
if ( frag == newTopFrag ) { if ( frag == newTopFrag ) {
break; break;
} }
@ -168,11 +168,10 @@ public class MainActivity extends XWActivity
private boolean dispatchNewIntentImpl( Intent intent ) private boolean dispatchNewIntentImpl( Intent intent )
{ {
boolean handled = false; boolean handled = false;
FragmentManager fm = getSupportFragmentManager();
for ( int ii = m_root.getChildCount() - 1; !handled && ii >= 0; --ii ) { for ( int ii = m_root.getChildCount() - 1; !handled && ii >= 0; --ii ) {
View child = m_root.getChildAt( ii ); View child = m_root.getChildAt( ii );
XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() ); XWFragment frag = findFragment( child );
if ( null != frag ) { if ( null != frag ) {
handled = frag.getDelegate().canHandleNewIntent( intent ); handled = frag.getDelegate().canHandleNewIntent( intent );
if ( handled ) { if ( handled ) {
@ -260,7 +259,8 @@ public class MainActivity extends XWActivity
public int m_request; public int m_request;
public int m_result; public int m_result;
public Intent m_data; 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<Fragment>(target); m_frag = new WeakReference<Fragment>(target);
m_request = request; m_request = request;
m_result = result; m_result = result;
@ -343,8 +343,7 @@ public class MainActivity extends XWActivity
XWFragment frag = null; XWFragment frag = null;
View child = m_root.getChildAt( m_root.getChildCount() - 1 ); View child = m_root.getChildAt( m_root.getChildCount() - 1 );
if ( null != child ) { if ( null != child ) {
frag = (XWFragment)getSupportFragmentManager() frag = findFragment( child );
.findFragmentById( child.getId() );
} }
return frag; return frag;
} }
@ -356,8 +355,7 @@ public class MainActivity extends XWActivity
XWFragment[] result = new XWFragment[count]; XWFragment[] result = new XWFragment[count];
for ( int ii = 0; ii < count; ++ii ) { for ( int ii = 0; ii < count; ++ii ) {
View child = m_root.getChildAt( childCount - 1 - ii ); View child = m_root.getChildAt( childCount - 1 - ii );
result[ii] = (XWFragment)getSupportFragmentManager() result[ii] = findFragment( child );
.findFragmentById( child.getId() );
} }
return result; return result;
@ -395,26 +393,30 @@ public class MainActivity extends XWActivity
private void trySetTitle( View view ) private void trySetTitle( View view )
{ {
XWFragment frag = (XWFragment) XWFragment frag = findFragment( view );
getSupportFragmentManager().findFragmentById( view.getId() );
if ( null != frag ) { if ( null != frag ) {
frag.setTitle(); frag.setTitle();
} else { } else {
DbgUtils.logd( TAG, "trySetTitle(): no fragment for id %x", DbgUtils.logd( TAG, "trySetTitle(): no fragment found" );
view.getId() );
} }
} }
private void setMenuVisibility( View cont, boolean visible ) private void setMenuVisibility( View cont, boolean visible )
{ {
FragmentManager fm = getSupportFragmentManager(); Fragment frag = findFragment( cont );
int hidingId = cont.getId();
Fragment frag = fm.findFragmentById( hidingId );
if ( null != frag ) { // hasn't been popped? if ( null != frag ) { // hasn't been popped?
frag.setMenuVisibility( visible ); 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, private void addFragmentImpl( Fragment fragment, Bundle bundle,
String parentName ) String parentName )
{ {
@ -471,7 +473,7 @@ public class MainActivity extends XWActivity
popUnneeded( fm, newName, parentName ); popUnneeded( fm, newName, parentName );
fm.beginTransaction() fm.beginTransaction()
.add( R.id.main_container, fragment ) .add( R.id.main_container, fragment, newName )
.addToBackStack( newName ) .addToBackStack( newName )
.commit(); .commit();
// Don't do this. It causes an exception if e.g. from fragment.start() // Don't do this. It causes an exception if e.g. from fragment.start()

View file

@ -33,6 +33,9 @@ import android.view.ViewGroup;
import android.widget.ListAdapter; import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Assert; import junit.framework.Assert;
abstract class XWFragment extends Fragment implements Delegator { abstract class XWFragment extends Fragment implements Delegator {
@ -43,6 +46,25 @@ abstract class XWFragment extends Fragment implements Delegator {
private String m_parentName; private String m_parentName;
private boolean m_hasOptionsMenu = false; private boolean m_hasOptionsMenu = false;
private static Set<XWFragment> sActiveFrags = new HashSet<XWFragment>();
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 ) public XWFragment setParentName( Delegator parent )
{ {
m_parentName = null == parent ? "<none>" m_parentName = null == parent ? "<none>"
@ -99,6 +121,7 @@ abstract class XWFragment extends Fragment implements Delegator {
Bundle savedInstanceState ) Bundle savedInstanceState )
{ {
DbgUtils.logd( TAG, "%s.onCreateView() called", getClass().getSimpleName() ); DbgUtils.logd( TAG, "%s.onCreateView() called", getClass().getSimpleName() );
sActiveFrags.add(this);
return m_dlgt.inflateView( inflater, container ); 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() ); DbgUtils.logd( TAG, "%s.onDestroy() called", getClass().getSimpleName() );
m_dlgt.onDestroy(); m_dlgt.onDestroy();
sActiveFrags.remove( this );
super.onDestroy(); super.onDestroy();
} }