make custom layout better on old android version

tweaks to BoardContainer and Toolbar to better position toolbar and
better hide/show it in tile exchange mode. The bar's still partially
offscreen sometimes on a 2.3.7 emulator but it's usable. Next I need to
try specifying the size of the bar rather than having it derive from the
size of the images it contains.
This commit is contained in:
Eric House 2016-08-18 11:30:32 -07:00
parent 9e81fb53b5
commit 2a8ce27ca9
3 changed files with 105 additions and 55 deletions

View file

@ -69,7 +69,9 @@ public class ABUtils {
public static boolean haveActionBar() public static boolean haveActionBar()
{ {
return null != s_safeInval; boolean result = null != s_safeInval;
// DbgUtils.logf( "haveActionBar() => %b", result );
return result;
} }
// http://stackoverflow.com/questions/10929579/how-to-check-if-android-phone-has-hardware-menu-button-in-android-2-1: // http://stackoverflow.com/questions/10929579/how-to-check-if-android-phone-has-hardware-menu-button-in-android-2-1:

View file

@ -26,12 +26,22 @@ import android.util.AttributeSet;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.View; import android.view.View;
import android.view.View.MeasureSpec;
import android.graphics.Rect;
import junit.framework.Assert; import junit.framework.Assert;
public class BoardContainer extends ViewGroup { public class BoardContainer extends ViewGroup {
private static final int TBAR_PCT_HOR = 90; // If the ratio of height/width exceeds this, use portrait layout
private static final int TBAR_PCT_VERT = 85; private static final int PORTRAIT_THRESHHOLD = 105;
private static final int BOARD_PCT_HOR = 90;
private static final int BOARD_PCT_VERT = 85;
private static final int BOARD_INDX = 0;
private static final int EXCH_INDX = 1;
private static final int VBAR_INDX = 2;
private static final int HBAR_INDX = 3;
private static boolean s_isPortrait = true; // initial assumption private static boolean s_isPortrait = true; // initial assumption
private static int s_width = 0; private static int s_width = 0;
@ -59,23 +69,29 @@ public class BoardContainer extends ViewGroup {
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{ {
final int childCount = getChildCount(); int width = MeasureSpec.getSize( widthMeasureSpec );
Assert.assertTrue( 4 == childCount ); int height = MeasureSpec.getSize( heightMeasureSpec );
int width = View.MeasureSpec.getSize( widthMeasureSpec );
int height = View.MeasureSpec.getSize( heightMeasureSpec );
if ( 0 != width || 0 != height ) { if ( 0 != width || 0 != height ) {
setForPortrait( width, height ); setForPortrait( width, height );
}
for ( int ii = 0; ii < childCount; ii++ ) { Rect[] rects = figureBounds( 0, 0, width, height );
final View child = getChildAt( ii );
if ( GONE != child.getVisibility() ) { // Measure the board
// Measure the child. measureChild( BOARD_INDX, rects[0] );
measureChild( child, widthMeasureSpec, heightMeasureSpec );
int childCount = getChildCount();
if ( 1 < childCount ) {
Assert.assertTrue( 4 == childCount );
if ( haveTradeBar() ) {
// Measure the exchange buttons bar
measureChild( EXCH_INDX, rects[1] );
}
// Measure the toolbar
measureChild( s_isPortrait ? HBAR_INDX : VBAR_INDX, rects[1] );
} }
} }
setMeasuredDimension( width, height ); setMeasuredDimension( width, height );
} }
@ -85,37 +101,42 @@ public class BoardContainer extends ViewGroup {
protected void onLayout( boolean changed, int left, int top, protected void onLayout( boolean changed, int left, int top,
int right, int bottom) int right, int bottom)
{ {
boolean haveTradeBar Rect[] rects = figureBounds( left, top, right, bottom );
= GONE != findViewById(R.id.exchange_buttons).getVisibility();
int boardHt = bottom - top;
if ( haveTradeBar || s_isPortrait ) {
boardHt = boardHt * TBAR_PCT_HOR / 100;
}
int boardWidth = right - left;
if ( !s_isPortrait ) {
boardWidth = boardWidth * TBAR_PCT_VERT / 100;
}
// layout the board // layout the board
BoardView board = (BoardView)getChildAt( 0 ); BoardView board = (BoardView)getChildAt( BOARD_INDX );
board.layout( left, top, left + boardWidth, top + boardHt ); layoutChild( board, rects[0] );
// The trade bar if ( 1 < getChildCount() ) {
if ( haveTradeBar ) {
LinearLayout exchButtons = (LinearLayout)getChildAt( 1 );
Assert.assertTrue( exchButtons.getId() == R.id.exchange_buttons );
exchButtons.layout( left, top + boardHt, right, bottom );
}
// Now one of the toolbars // The trade bar
View scrollView = getChildAt( s_isPortrait ? 3 : 2 ); if ( haveTradeBar() ) {
Assert.assertTrue( GONE != scrollView.getVisibility() ); LinearLayout exchButtons = (LinearLayout)getChildAt( EXCH_INDX );
if ( s_isPortrait ) { Assert.assertTrue( exchButtons.getId() == R.id.exchange_buttons );
top += boardHt; layoutChild( exchButtons, rects[1] );
} else { }
left += boardWidth;
// Now one of the toolbars
View scrollView = getChildAt( s_isPortrait ? HBAR_INDX : VBAR_INDX );
if ( GONE != scrollView.getVisibility() ) {
layoutChild( scrollView, rects[1] );
}
} }
scrollView.layout( left, top, right, bottom ); }
private void measureChild( int index, Rect rect )
{
int childWidthSpec = MeasureSpec.makeMeasureSpec(rect.width(),
MeasureSpec.AT_MOST );
int childHeightSpec = MeasureSpec.makeMeasureSpec(rect.height(),
MeasureSpec.AT_MOST );
View view = getChildAt( index );
measureChild( view, childWidthSpec, childHeightSpec );
}
private void layoutChild( View child, Rect rect )
{
child.layout( rect.left, rect.top, rect.right, rect.bottom );
} }
private void setForPortrait( final int width, final int height ) private void setForPortrait( final int width, final int height )
@ -123,7 +144,7 @@ public class BoardContainer extends ViewGroup {
if ( height != s_height || width != s_width ) { if ( height != s_height || width != s_width ) {
s_height = height; s_height = height;
s_width = width; s_width = width;
s_isPortrait = height > width; s_isPortrait = PORTRAIT_THRESHHOLD < (height*100) / width;
findViewById( R.id.tbar_parent_hor ) findViewById( R.id.tbar_parent_hor )
.setVisibility( s_isPortrait ? VISIBLE : GONE ); .setVisibility( s_isPortrait ? VISIBLE : GONE );
findViewById( R.id.tbar_parent_vert ) findViewById( R.id.tbar_parent_vert )
@ -133,6 +154,39 @@ public class BoardContainer extends ViewGroup {
} }
} }
private Rect[] figureBounds( int left, int top, int width, int height )
{
int boardHeight = ( haveTradeBar() || s_isPortrait)
? height * BOARD_PCT_HOR / 100 : height;
int boardWidth = s_isPortrait ? width : width * BOARD_PCT_VERT / 100;
// board
Rect boardBounds = new Rect( left, top, left + boardWidth,
top + boardHeight );
// DbgUtils.logf( "BoardContainer: boardBounds: %s", boardBounds.toString() );
// toolbar
if ( s_isPortrait ) {
top += boardHeight;
height -= boardHeight;
} else {
left += boardWidth;
width -= boardWidth;
}
Rect toolsBounds = new Rect( left, top, left + width, top + height );
// DbgUtils.logf( "BoardContainer: toolsBounds: %s", toolsBounds.toString() );
return new Rect[] { boardBounds, toolsBounds };
}
private boolean haveTradeBar()
{
boolean result = false;
if ( s_isPortrait && 1 < getChildCount() ) {
View bar = getChildAt( 1 );
result = null != bar && GONE != bar.getVisibility();
}
return result;
}
private static void callSCL() private static void callSCL()
{ {
if ( 0 != s_width || 0 != s_height ) { if ( 0 != s_width || 0 != s_height ) {

View file

@ -81,7 +81,7 @@ public class Toolbar implements BoardContainer.SizeChangeListener {
{ {
if ( m_visible != visible ) { if ( m_visible != visible ) {
m_visible = visible; m_visible = visible;
doShowHide( null ); doShowHide();
} }
} }
@ -134,10 +134,9 @@ public class Toolbar implements BoardContainer.SizeChangeListener {
// SizeChangeListener // SizeChangeListener
public void sizeChanged( int width, int height, boolean isPortrait ) public void sizeChanged( int width, int height, boolean isPortrait )
{ {
DbgUtils.logf( "Toolbar.sizeChanged(isPortrait=%b)", isPortrait );
tryAddListeners( m_onClickListeners ); tryAddListeners( m_onClickListeners );
tryAddListeners( m_onLongClickListeners ); tryAddListeners( m_onLongClickListeners );
doShowHide( new Boolean(isPortrait) ); doShowHide();
} }
private void tryAddListeners( Map<Buttons, Object> map ) private void tryAddListeners( Map<Buttons, Object> map )
@ -168,14 +167,10 @@ public class Toolbar implements BoardContainer.SizeChangeListener {
return success; return success;
} }
private void doShowHide( Boolean shouldBePortrait ) private void doShowHide()
{ {
// BoardContainer owns which scroller we'll use, and signals its boolean isPortrait = BoardContainer.getIsPortrait();
// choice by setting their visibility. We use the one that's visible. DbgUtils.logdf( "Toolbar.doShowHide(): isPortrait: %b", isPortrait );
boolean isPortrait = View.GONE != m_scrollHor.getVisibility();
DbgUtils.logf( "Toolbar.doShowHide(): isPortrait: %b", isPortrait );
Assert.assertTrue( null == shouldBePortrait
|| shouldBePortrait.equals(isPortrait) );
if ( null == m_layout ) { if ( null == m_layout ) {
m_layout = (LinearLayout)LocUtils.inflate( m_activity, R.layout.toolbar ); m_layout = (LinearLayout)LocUtils.inflate( m_activity, R.layout.toolbar );
@ -186,13 +181,12 @@ public class Toolbar implements BoardContainer.SizeChangeListener {
LinearLayout.HORIZONTAL : LinearLayout.VERTICAL ); LinearLayout.HORIZONTAL : LinearLayout.VERTICAL );
ViewGroup scroller = isPortrait ? m_scrollHor : m_scrollVert; ViewGroup scroller = isPortrait ? m_scrollHor : m_scrollVert;
Assert.assertNotNull( scroller );
if ( null != scroller ) { if ( null != scroller ) {
// Google's had reports of a crash adding second view // Google's had reports of a crash adding second view
scroller.removeAllViews(); scroller.removeAllViews();
scroller.addView( m_layout ); scroller.addView( m_layout );
}
m_layout.setVisibility( m_visible? View.VISIBLE : View.GONE ); scroller.setVisibility( m_visible? View.VISIBLE : View.GONE );
}
} }
} }