From 352508b85284a30280b5b2bdfd5cbd23bd12f704 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 31 Jan 2017 07:01:11 -0800 Subject: [PATCH] start fixing problems with dual-pane Remove the generated FrameLayout that was breaking restoration after a config change. Set layout_weight=1 for all fragment root views so they get half the screen in landscape mode. Remove some code. Problems remain, first among them that notification intents aren't dispatched correctly. --- .../org/eehouse/android/xw4/MainActivity.java | 133 ++++-------------- .../org/eehouse/android/xw4/XWFragment.java | 2 + .../android/app/src/main/res/layout/board.xml | 1 + .../android/app/src/main/res/layout/chat.xml | 5 +- .../app/src/main/res/layout/dict_browse.xml | 5 +- .../app/src/main/res/layout/dict_browser.xml | 1 + .../app/src/main/res/layout/game_list.xml | 1 + 7 files changed, 41 insertions(+), 107 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 95f5fcd48..9aa9e6eab 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 @@ -31,7 +31,6 @@ import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem; import android.view.View; -import android.widget.FrameLayout; import android.widget.LinearLayout; import junit.framework.Assert; @@ -52,9 +51,6 @@ public class MainActivity extends XWActivity // Used only if m_dpEnabled is true private LinearLayout m_root; - private int m_maxPanes; - private int m_nextID = 0x00FFFFFF; - private Boolean m_isPortrait; private boolean m_safeToCommit; private ArrayList m_runWhenSafe = new ArrayList(); private Intent m_newIntent; // work in progress... @@ -76,8 +72,6 @@ public class MainActivity extends XWActivity m_root = (LinearLayout)findViewById( R.id.main_container ); getSupportFragmentManager().addOnBackStackChangedListener( this ); - m_maxPanes = maxPanes(); - // Nothing to do if we're restarting if ( savedInstanceState == null ) { // In case this activity was started with special instructions from an Intent, @@ -102,6 +96,7 @@ public class MainActivity extends XWActivity { setSafeToRun(); super.onPostResume(); + setVisiblePanes(); } // called when we're brought to the front (probably as a result of @@ -114,33 +109,6 @@ public class MainActivity extends XWActivity m_dlgt.handleNewIntent( intent ); } - @Override - public void onConfigurationChanged( Configuration newConfig ) - { - if ( m_dpEnabled ) { - Rect rect = new Rect(); - m_root.getWindowVisibleDisplayFrame( rect ); - - boolean isPortrait - = Configuration.ORIENTATION_PORTRAIT == newConfig.orientation; - DbgUtils.logi( TAG, "onConfigurationChanged(isPortrait=%b)", - isPortrait ); - m_isPortrait = isPortrait; - if ( isPortrait != (rect.width() <= rect.height()) ) { - DbgUtils.logd( TAG, "onConfigurationChanged(): isPortrait:" - + " %b; width: %d; height: %d", - isPortrait, rect.width(), rect.height() ); - } - int maxPanes = isPortrait? 1 : MAX_PANES_LANDSCAPE; - if ( m_maxPanes != maxPanes ) { - m_maxPanes = maxPanes; - setVisiblePanes(); - } - tellOrientationChanged(); - } - super.onConfigurationChanged( newConfig ); - } - /* Sometimes I'm getting crashes because views don't have fragments * associated yet. I suspect that's because adding them's been postponed * via the m_runWhenSafe mechanism. So: postpone handling intents too. @@ -349,8 +317,8 @@ public class MainActivity extends XWActivity child.getId() ); } m_root.removeView( child ); - setVisiblePanes(); } + setVisiblePanes(); // If there's a pending on-result call, make it. if ( null != m_pendingResult ) { @@ -384,7 +352,7 @@ public class MainActivity extends XWActivity private XWFragment[] getVisibleFragments() { int childCount = m_root.getChildCount(); - int count = Math.min( m_maxPanes, childCount ); + int count = Math.min( maxPanes(), childCount ); XWFragment[] result = new XWFragment[count]; for ( int ii = 0; ii < count; ++ii ) { View child = m_root.getChildAt( childCount - 1 - ii ); @@ -395,23 +363,6 @@ public class MainActivity extends XWActivity return result; } - // Walk all Fragment children and if they care notify of change. - private void tellOrientationChanged() - { - FragmentManager fm = getSupportFragmentManager(); - int nPanes = m_root.getChildCount(); - for ( int ii = 0; ii < nPanes; ++ii ) { - FrameLayout frame = (FrameLayout)m_root.getChildAt( ii ); - int id = frame.getId(); - Fragment frag = fm.findFragmentById( id ); - if ( null == frag ) { - DbgUtils.logw( TAG,"tellOrienationChanged: NO FRAG at %d, id=%d", ii, id ); - } else if ( frag instanceof XWFragment ) { - ((XWFragment)frag).getDelegate().orientationChanged(); - } - } - } - private int maxPanes() { int result; @@ -422,7 +373,7 @@ public class MainActivity extends XWActivity } else { result = 1; } - // DbgUtils.logf( "maxPanes() => %d", result ); + // DbgUtils.logd( TAG, "maxPanes() => %d", result ); return result; } @@ -430,10 +381,10 @@ public class MainActivity extends XWActivity { // hide all but the right-most m_maxPanes children int nPanes = m_root.getChildCount(); + int maxPanes = maxPanes(); for ( int ii = 0; ii < nPanes; ++ii ) { View child = m_root.getChildAt( ii ); - boolean visible = ii >= nPanes - m_maxPanes; - DbgUtils.logi( TAG, "pane %d: visible=%b", ii, visible ); + boolean visible = ii >= nPanes - maxPanes; child.setVisibility( visible ? View.VISIBLE : View.GONE ); setMenuVisibility( child, visible ); if ( visible ) { @@ -456,9 +407,8 @@ public class MainActivity extends XWActivity private void setMenuVisibility( View cont, boolean visible ) { - FrameLayout layout = (FrameLayout)cont; FragmentManager fm = getSupportFragmentManager(); - int hidingId = layout.getId(); + int hidingId = cont.getId(); Fragment frag = fm.findFragmentById( hidingId ); if ( null != frag ) { // hasn't been popped? frag.setMenuVisibility( visible ); @@ -491,60 +441,37 @@ public class MainActivity extends XWActivity } } + private void popUnneeded( FragmentManager fm, String newName, String parentName ) + { + final int fragCount = fm.getBackStackEntryCount(); + int lastKept = fragCount; + for ( int ii = 0; ii < fragCount; ++ii ) { + FragmentManager.BackStackEntry entry = fm.getBackStackEntryAt( ii ); + String entryName = entry.getName(); + if ( entryName.equals( newName ) ) { + lastKept = ii - 1; // keep only my parent; kill my same-class sibling! + break; + } else if ( entryName.equals(parentName) ) { + lastKept = ii; + break; + } + } + + for ( int ii = fragCount - 1; ii > lastKept; --ii ) { + fm.popBackStack(); + } + } + private void safeAddFragment( Fragment fragment, String parentName ) { Assert.assertTrue( m_safeToCommit ); String newName = fragment.getClass().getSimpleName(); - boolean replace = false; FragmentManager fm = getSupportFragmentManager(); - int fragCount = fm.getBackStackEntryCount(); - int containerCount = m_root.getChildCount(); - DbgUtils.logi( TAG, "fragCount: %d; containerCount: %d", fragCount, containerCount ); - // Assert.assertTrue( fragCount == containerCount ); - // Replace IF we're adding something of the same class at right OR if - // we're adding something with the existing left pane as its parent - // (delegator) - if ( 1 < fragCount ) { - Assert.assertTrue( MAX_PANES_LANDSCAPE == 2 ); // otherwise FIXME - FragmentManager.BackStackEntry entry - = fm.getBackStackEntryAt( fragCount - 2 ); - String curName = entry.getName(); - // DbgUtils.logf( "comparing %s, %s", curName, parentName ); - replace = curName.equals( parentName ); - } - - if ( replace ) { - fm.popBackStack(); - } - - // Replace doesn't seem to work with generated IDs, so we'll create a - // new FrameLayout each time. If we're replacing, we'll replace the - // current rightmost FrameLayout. Otherwise we'll add a new one. - LinearLayout.LayoutParams lp - = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams - .MATCH_PARENT, 1.0f); - FrameLayout cont = new FrameLayout( this ); - cont.setLayoutParams( lp ); - int id = --m_nextID; - cont.setId( id ); - if ( LOG_IDS ) { - DbgUtils.logi( TAG, "assigning id %x to view with name %s", id, newName ); - } - m_root.addView( cont, replace ? containerCount - 1 : containerCount ); - - if ( !replace && containerCount >= m_maxPanes ) { - int indx = containerCount - m_maxPanes; - View child = m_root.getChildAt( indx ); - child.setVisibility( View.GONE ); - - setMenuVisibility( child, false ); - - DbgUtils.logi( TAG, "hiding %dth container", indx ); - } + popUnneeded( fm, newName, parentName ); fm.beginTransaction() - .add( id, fragment ) + .add( R.id.main_container, fragment ) .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 54ec1b7c3..5dce96b1e 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 @@ -69,6 +69,7 @@ abstract class XWFragment extends Fragment implements Delegator { super.onSaveInstanceState( outState ); Assert.assertNotNull( m_parentName ); outState.putString( PARENT_NAME, m_parentName ); + m_dlgt.onSaveInstanceState( outState ); } protected void onCreate( DelegateBase dlgt, Bundle sis ) @@ -79,6 +80,7 @@ abstract class XWFragment extends Fragment implements Delegator { m_parentName = sis.getString( PARENT_NAME ); Assert.assertNotNull( m_parentName ); } + Assert.assertNull( m_dlgt ); m_dlgt = dlgt; } diff --git a/xwords4/android/app/src/main/res/layout/board.xml b/xwords4/android/app/src/main/res/layout/board.xml index 2c0884293..d914565c2 100644 --- a/xwords4/android/app/src/main/res/layout/board.xml +++ b/xwords4/android/app/src/main/res/layout/board.xml @@ -10,6 +10,7 @@ android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" + android:layout_weight="1" >