mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-18 22:26:30 +01:00
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:
parent
9e81fb53b5
commit
2a8ce27ca9
3 changed files with 105 additions and 55 deletions
|
@ -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:
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
Rect[] rects = figureBounds( 0, 0, width, height );
|
||||||
|
|
||||||
|
// Measure the board
|
||||||
|
measureChild( BOARD_INDX, rects[0] );
|
||||||
|
|
||||||
|
int childCount = getChildCount();
|
||||||
|
if ( 1 < childCount ) {
|
||||||
|
Assert.assertTrue( 4 == childCount );
|
||||||
|
|
||||||
|
if ( haveTradeBar() ) {
|
||||||
|
// Measure the exchange buttons bar
|
||||||
|
measureChild( EXCH_INDX, rects[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int ii = 0; ii < childCount; ii++ ) {
|
// Measure the toolbar
|
||||||
final View child = getChildAt( ii );
|
measureChild( s_isPortrait ? HBAR_INDX : VBAR_INDX, rects[1] );
|
||||||
if ( GONE != child.getVisibility() ) {
|
|
||||||
// Measure the child.
|
|
||||||
measureChild( child, widthMeasureSpec, heightMeasureSpec );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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] );
|
||||||
|
|
||||||
|
if ( 1 < getChildCount() ) {
|
||||||
|
|
||||||
// The trade bar
|
// The trade bar
|
||||||
if ( haveTradeBar ) {
|
if ( haveTradeBar() ) {
|
||||||
LinearLayout exchButtons = (LinearLayout)getChildAt( 1 );
|
LinearLayout exchButtons = (LinearLayout)getChildAt( EXCH_INDX );
|
||||||
Assert.assertTrue( exchButtons.getId() == R.id.exchange_buttons );
|
Assert.assertTrue( exchButtons.getId() == R.id.exchange_buttons );
|
||||||
exchButtons.layout( left, top + boardHt, right, bottom );
|
layoutChild( exchButtons, rects[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now one of the toolbars
|
// Now one of the toolbars
|
||||||
View scrollView = getChildAt( s_isPortrait ? 3 : 2 );
|
View scrollView = getChildAt( s_isPortrait ? HBAR_INDX : VBAR_INDX );
|
||||||
Assert.assertTrue( GONE != scrollView.getVisibility() );
|
if ( GONE != scrollView.getVisibility() ) {
|
||||||
if ( s_isPortrait ) {
|
layoutChild( scrollView, rects[1] );
|
||||||
top += boardHt;
|
|
||||||
} else {
|
|
||||||
left += boardWidth;
|
|
||||||
}
|
}
|
||||||
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 ) {
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue