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.
This commit is contained in:
Eric House 2017-01-31 07:01:11 -08:00
parent f9cc524028
commit 352508b852
7 changed files with 41 additions and 107 deletions

View file

@ -31,7 +31,6 @@ import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import junit.framework.Assert; import junit.framework.Assert;
@ -52,9 +51,6 @@ public class MainActivity extends XWActivity
// Used only if m_dpEnabled is true // Used only if m_dpEnabled is true
private LinearLayout m_root; private LinearLayout m_root;
private int m_maxPanes;
private int m_nextID = 0x00FFFFFF;
private Boolean m_isPortrait;
private boolean m_safeToCommit; private boolean m_safeToCommit;
private ArrayList<Runnable> m_runWhenSafe = new ArrayList<Runnable>(); private ArrayList<Runnable> m_runWhenSafe = new ArrayList<Runnable>();
private Intent m_newIntent; // work in progress... private Intent m_newIntent; // work in progress...
@ -76,8 +72,6 @@ public class MainActivity extends XWActivity
m_root = (LinearLayout)findViewById( R.id.main_container ); m_root = (LinearLayout)findViewById( R.id.main_container );
getSupportFragmentManager().addOnBackStackChangedListener( this ); getSupportFragmentManager().addOnBackStackChangedListener( this );
m_maxPanes = maxPanes();
// Nothing to do if we're restarting // Nothing to do if we're restarting
if ( savedInstanceState == null ) { if ( savedInstanceState == null ) {
// In case this activity was started with special instructions from an Intent, // In case this activity was started with special instructions from an Intent,
@ -102,6 +96,7 @@ public class MainActivity extends XWActivity
{ {
setSafeToRun(); setSafeToRun();
super.onPostResume(); super.onPostResume();
setVisiblePanes();
} }
// called when we're brought to the front (probably as a result of // 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 ); 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 /* Sometimes I'm getting crashes because views don't have fragments
* associated yet. I suspect that's because adding them's been postponed * associated yet. I suspect that's because adding them's been postponed
* via the m_runWhenSafe mechanism. So: postpone handling intents too. * via the m_runWhenSafe mechanism. So: postpone handling intents too.
@ -349,8 +317,8 @@ public class MainActivity extends XWActivity
child.getId() ); child.getId() );
} }
m_root.removeView( child ); m_root.removeView( child );
setVisiblePanes();
} }
setVisiblePanes();
// If there's a pending on-result call, make it. // If there's a pending on-result call, make it.
if ( null != m_pendingResult ) { if ( null != m_pendingResult ) {
@ -384,7 +352,7 @@ public class MainActivity extends XWActivity
private XWFragment[] getVisibleFragments() private XWFragment[] getVisibleFragments()
{ {
int childCount = m_root.getChildCount(); int childCount = m_root.getChildCount();
int count = Math.min( m_maxPanes, childCount ); int count = Math.min( maxPanes(), childCount );
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 );
@ -395,23 +363,6 @@ public class MainActivity extends XWActivity
return result; 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() private int maxPanes()
{ {
int result; int result;
@ -422,7 +373,7 @@ public class MainActivity extends XWActivity
} else { } else {
result = 1; result = 1;
} }
// DbgUtils.logf( "maxPanes() => %d", result ); // DbgUtils.logd( TAG, "maxPanes() => %d", result );
return result; return result;
} }
@ -430,10 +381,10 @@ public class MainActivity extends XWActivity
{ {
// hide all but the right-most m_maxPanes children // hide all but the right-most m_maxPanes children
int nPanes = m_root.getChildCount(); int nPanes = m_root.getChildCount();
int maxPanes = maxPanes();
for ( int ii = 0; ii < nPanes; ++ii ) { for ( int ii = 0; ii < nPanes; ++ii ) {
View child = m_root.getChildAt( ii ); View child = m_root.getChildAt( ii );
boolean visible = ii >= nPanes - m_maxPanes; boolean visible = ii >= nPanes - maxPanes;
DbgUtils.logi( TAG, "pane %d: visible=%b", ii, visible );
child.setVisibility( visible ? View.VISIBLE : View.GONE ); child.setVisibility( visible ? View.VISIBLE : View.GONE );
setMenuVisibility( child, visible ); setMenuVisibility( child, visible );
if ( visible ) { if ( visible ) {
@ -456,9 +407,8 @@ public class MainActivity extends XWActivity
private void setMenuVisibility( View cont, boolean visible ) private void setMenuVisibility( View cont, boolean visible )
{ {
FrameLayout layout = (FrameLayout)cont;
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
int hidingId = layout.getId(); int hidingId = cont.getId();
Fragment frag = fm.findFragmentById( hidingId ); 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 );
@ -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 ) private void safeAddFragment( Fragment fragment, String parentName )
{ {
Assert.assertTrue( m_safeToCommit ); Assert.assertTrue( m_safeToCommit );
String newName = fragment.getClass().getSimpleName(); String newName = fragment.getClass().getSimpleName();
boolean replace = false;
FragmentManager fm = getSupportFragmentManager(); 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 popUnneeded( fm, newName, parentName );
// 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 );
}
fm.beginTransaction() fm.beginTransaction()
.add( id, fragment ) .add( R.id.main_container, fragment )
.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

@ -69,6 +69,7 @@ abstract class XWFragment extends Fragment implements Delegator {
super.onSaveInstanceState( outState ); super.onSaveInstanceState( outState );
Assert.assertNotNull( m_parentName ); Assert.assertNotNull( m_parentName );
outState.putString( PARENT_NAME, m_parentName ); outState.putString( PARENT_NAME, m_parentName );
m_dlgt.onSaveInstanceState( outState );
} }
protected void onCreate( DelegateBase dlgt, Bundle sis ) protected void onCreate( DelegateBase dlgt, Bundle sis )
@ -79,6 +80,7 @@ abstract class XWFragment extends Fragment implements Delegator {
m_parentName = sis.getString( PARENT_NAME ); m_parentName = sis.getString( PARENT_NAME );
Assert.assertNotNull( m_parentName ); Assert.assertNotNull( m_parentName );
} }
Assert.assertNull( m_dlgt );
m_dlgt = dlgt; m_dlgt = dlgt;
} }

View file

@ -10,6 +10,7 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1"
> >
<org.eehouse.android.xw4.BoardView <org.eehouse.android.xw4.BoardView

View file

@ -2,8 +2,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="match_parent"
android:layout_weight="1"
> >
<ScrollView android:id="@+id/scroll" <ScrollView android:id="@+id/scroll"

View file

@ -2,8 +2,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="match_parent"
android:layout_weight="1"
> >
<CheckBox android:id="@+id/show_remote" <CheckBox android:id="@+id/show_remote"

View file

@ -6,6 +6,7 @@
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:layout_weight="1"
> >
<TextView android:id="@+id/desc" <TextView android:id="@+id/desc"

View file

@ -4,6 +4,7 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1"
> >
<ListView android:id="@id/android:list" <ListView android:id="@id/android:list"