mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
simplify intent dispatch
Too-clever double loop had an no-exit path. Now it's simpler: find a fragment that can handle the intent, pop all fragments to its right until it becomes top-most (there may be none), and then give it the intent. Use of popBackStackImmediate() is required so old fragments are gone before intent handling wants to create new ones.
This commit is contained in:
parent
c0eb827b77
commit
7358c1a185
4 changed files with 48 additions and 46 deletions
|
@ -570,10 +570,11 @@ public class DelegateBase implements DlgClickNotify,
|
|||
|
||||
protected boolean isVisible() { return m_isVisible; }
|
||||
|
||||
protected boolean handleNewIntent( Intent intent ) {
|
||||
protected boolean canHandleNewIntent( Intent intent ) { return false; }
|
||||
|
||||
protected void handleNewIntent( Intent intent ) {
|
||||
DbgUtils.logf( "%s.handleNewIntent(%s): not handling",
|
||||
getClass().getSimpleName(), intent.toString() );
|
||||
return false; // not handled
|
||||
}
|
||||
|
||||
protected void runWhenActive( Runnable proc )
|
||||
|
|
|
@ -56,12 +56,11 @@ public class DualpaneDelegate extends DelegateBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleNewIntent( Intent intent )
|
||||
protected void handleNewIntent( Intent intent )
|
||||
{
|
||||
MainActivity main = (MainActivity)m_activity;
|
||||
boolean handled = main.dispatchNewIntent( intent );
|
||||
DbgUtils.logf( "DualpaneDelegate.handleNewIntent() => %b", handled );
|
||||
return handled;
|
||||
main.dispatchNewIntent( intent );
|
||||
DbgUtils.logf( "DualpaneDelegate.handleNewIntent()" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -983,14 +983,19 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
} // init
|
||||
|
||||
@Override
|
||||
protected boolean handleNewIntent( Intent intent )
|
||||
protected boolean canHandleNewIntent( Intent intent )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleNewIntent( Intent intent )
|
||||
{
|
||||
m_launchedGames.clear();
|
||||
Assert.assertNotNull( intent );
|
||||
invalRelayIDs( intent.getStringArrayExtra( RELAYIDS_EXTRA ) );
|
||||
reloadGame( intent.getLongExtra( ROWID_EXTRA, -1 ) );
|
||||
tryStartsFromIntent( intent );
|
||||
return true; // handled it
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -169,56 +169,53 @@ public class MainActivity extends XWActivity
|
|||
return handled;
|
||||
}
|
||||
|
||||
private void popIntoView( XWFragment newTopFrag )
|
||||
{
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
for ( ; ; ) {
|
||||
int top = m_root.getChildCount() - 1;
|
||||
if ( top < 0 ) {
|
||||
break;
|
||||
}
|
||||
View child = m_root.getChildAt( top );
|
||||
XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() );
|
||||
if ( frag == newTopFrag ) {
|
||||
break;
|
||||
}
|
||||
String name = frag.getClass().getSimpleName();
|
||||
DbgUtils.logdf( "MainActivity.popIntoView(): popping %d: %s", top, name );
|
||||
fm.popBackStackImmediate();
|
||||
DbgUtils.logdf( "MainActivity.popIntoView(): DONE popping %s",
|
||||
name );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run down the list of fragments until one handles the intent. If no
|
||||
* visible one does, pop hidden ones into view until one of them
|
||||
* does. Yes, this will take us back to GamesList being visible even if
|
||||
* nothing handles the intent, but at least now all are handled by
|
||||
* GamesList anyway.
|
||||
* Run down the list of fragments until one can handle the intent. If
|
||||
* necessary, pop fragments above it until it comes into view. Then send
|
||||
* it the event.
|
||||
*/
|
||||
private boolean dispatchNewIntentImpl( Intent intent )
|
||||
{
|
||||
boolean handled = false;
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
|
||||
// First try non-left-most fragments, if any. Once we've eliminated
|
||||
// them we can just iterate on the leftmost fragment.
|
||||
int nNonLeft = m_maxPanes - 1;
|
||||
// include paged-to-left invisible views
|
||||
int viewCount = m_root.getChildCount();
|
||||
for ( int ii = nNonLeft; !handled && 0 < ii; --ii ) {
|
||||
View child = m_root.getChildAt( viewCount - ii );
|
||||
Fragment frag = fm.findFragmentById( child.getId() );
|
||||
handled = ((XWFragment)frag).getDelegate().handleNewIntent( intent );
|
||||
}
|
||||
|
||||
while ( !handled ) {
|
||||
// Now iterate on the leftmost, popping if necessary to page new
|
||||
// ones into place
|
||||
int childCount = m_root.getChildCount();
|
||||
int hiddenCount = Math.max( 0, childCount - m_maxPanes );
|
||||
for ( int ii = hiddenCount; ii >= 0; --ii ) {
|
||||
View child = m_root.getChildAt( ii );
|
||||
if ( null == child ) {
|
||||
DbgUtils.logf( "no child at index %d", ii );
|
||||
continue;
|
||||
}
|
||||
Fragment frag = fm.findFragmentById( child.getId() );
|
||||
// DbgUtils.logf( "left-most case (child %d): %s", hiddenCount,
|
||||
// frag.getClass().getSimpleName() );
|
||||
handled = ((XWFragment)frag).getDelegate()
|
||||
.handleNewIntent( intent );
|
||||
|
||||
for ( int ii = m_root.getChildCount() - 1; !handled && ii >= 0; --ii ) {
|
||||
View child = m_root.getChildAt( ii );
|
||||
XWFragment frag = (XWFragment)fm.findFragmentById( child.getId() );
|
||||
if ( null != frag ) {
|
||||
handled = frag.getDelegate().canHandleNewIntent( intent );
|
||||
if ( handled ) {
|
||||
break;
|
||||
} else if ( ii > 0 ) {
|
||||
DbgUtils.logf( "popping %s",
|
||||
frag.getClass().getSimpleName() );
|
||||
fm.popBackStackImmediate(); // callback removes view
|
||||
popIntoView( frag );
|
||||
frag.getDelegate().handleNewIntent( intent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( BuildConfig.DEBUG && !handled ) {
|
||||
DbgUtils.showf( this, "dropping intent %s", intent.toString() );
|
||||
DbgUtils.logdf( "dropping intent %s", intent.toString() );
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue