Android: 如何使自定义视图只显示可用屏幕 space?
Android: How to make a custom view take only the available screen space?
我有两个自定义视图,我想对其进行垂直布局。
第一个视图是一种游戏板,它是一个正方形。正方形很容易缩放,几乎可以适应任何可用的 space.
第二个视图是 [TableLayout][1]
的子类,其中包含多个 Button
。 rows/columns的数量是在运行时确定的。
为了便于解释,我将第一个视图称为 board,将第二个视图称为 table.
我希望 board 显示在屏幕顶部,table 应该在它的正下方。 Table 应该取它需要的垂直 space (这基本上取决于行数)。 Board 应将其方形边缘尺寸设置为可用宽度和可用高度中的最小值,即按比例缩小。
我尝试使用 [RelativeLayout][2]
实现此目的,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
/>
<some.package.Board
android:id="@+id/board"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_above="@id/table"
/>
</RelativeLayout>
通过这种方法,我希望首先测量 table 并将剩余的可用屏幕高度作为最大值传递(即 AT_MOST
) board 的 onMeasure
的高度规格。这个假设似乎是错误的。
当我使用这个布局时,板似乎被调整为零大小,即它没有被渲染。
当我这样扭转局面时:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Board
android:id="@+id/board"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
android:layout_below="@id/board"
/>
</RelativeLayout>
board 占据太多垂直 space 并且 table 在底部被切断
在这两种情况下,board 显示宽度为 AT_MOST
宽度规格,显示高度(减去状态栏和操作栏高度)为 AT_MOST
高度规格所以我的 onMeasure
实现采用两者中的最小值作为正方形大小,这没有为 table 视图留出足够的空间。
谁能告诉我如何处理这个问题,好吗?
我可能需要添加嵌套布局吗?或者使用布局权重? - 我没有这样做,因为在我的理解中权重是相对大小的。
谢谢和亲切的问候
在 Gabe 的回答后编辑:
在尝试了 Gabe 的建议后,我在 board 和 table 的 onMeasure
方法中记录了一些数据:
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=0
I/Choreographer﹕ Skipped 206 frames! The application may be doing too much work on its main thread.
D/dalvikvm﹕ GC_FOR_ALLOC freed 305K, 8% free 4880K/5252K, paused 103ms, total 105ms
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=0
wM 是MeasureSpec
的宽度模式,minW 是getSuggestedMinimumWidth()
,ws 是MeasureSpec
的宽度大小。
这同样适用于 hM、minH 和 hs。
我在 table 中 not 覆盖了 onMeasure
(是的,我有,但它只是记录数据并调用 super.onMeasure()
)。 board.onMeasure()
中实现的行为如上所述。
我还在疑惑...
在 kha 的回答后编辑:
kha 的建议奏效了。工作 XML 布局是
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
android:layout_alignParentBottom="true"
/>
<some.package.Board
android:id="@+id/board"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_above="@id/table"
/>
</RelativeLayout>
日志输出现在是:
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=702
I/Choreographer﹕ Skipped 118 frames! The application may be doing too much work on its main thread.
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=702
相对布局中视图的顺序决定了它们重叠时的 z 顺序,而不是它们的绘制顺序。此外,权重只对线性布局起作用,对相对布局不起作用。
第二个 XML 几乎是正确的 - 它会测量出 table,让它占用尽可能多的空间,然后在它下面布置电路板。将板的高度更改为 match_parent 它应该可以工作 - 它会强制它占用的空间不超过剩余空间。
试试这个:
移动并更改
android:layout_below="@id/board"
到
android:layout_above="@id/table"
在您的其他布局上。
结合 table 布局上的设置 android:alignParentBottom=true
执行此操作。
我有两个自定义视图,我想对其进行垂直布局。 第一个视图是一种游戏板,它是一个正方形。正方形很容易缩放,几乎可以适应任何可用的 space.
第二个视图是 [TableLayout][1]
的子类,其中包含多个 Button
。 rows/columns的数量是在运行时确定的。
为了便于解释,我将第一个视图称为 board,将第二个视图称为 table.
我希望 board 显示在屏幕顶部,table 应该在它的正下方。 Table 应该取它需要的垂直 space (这基本上取决于行数)。 Board 应将其方形边缘尺寸设置为可用宽度和可用高度中的最小值,即按比例缩小。
我尝试使用 [RelativeLayout][2]
实现此目的,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
/>
<some.package.Board
android:id="@+id/board"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_above="@id/table"
/>
</RelativeLayout>
通过这种方法,我希望首先测量 table 并将剩余的可用屏幕高度作为最大值传递(即 AT_MOST
) board 的 onMeasure
的高度规格。这个假设似乎是错误的。
当我使用这个布局时,板似乎被调整为零大小,即它没有被渲染。
当我这样扭转局面时:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Board
android:id="@+id/board"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
android:layout_below="@id/board"
/>
</RelativeLayout>
board 占据太多垂直 space 并且 table 在底部被切断
在这两种情况下,board 显示宽度为 AT_MOST
宽度规格,显示高度(减去状态栏和操作栏高度)为 AT_MOST
高度规格所以我的 onMeasure
实现采用两者中的最小值作为正方形大小,这没有为 table 视图留出足够的空间。
谁能告诉我如何处理这个问题,好吗? 我可能需要添加嵌套布局吗?或者使用布局权重? - 我没有这样做,因为在我的理解中权重是相对大小的。
谢谢和亲切的问候
在 Gabe 的回答后编辑:
在尝试了 Gabe 的建议后,我在 board 和 table 的 onMeasure
方法中记录了一些数据:
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=0
I/Choreographer﹕ Skipped 206 frames! The application may be doing too much work on its main thread.
D/dalvikvm﹕ GC_FOR_ALLOC freed 305K, 8% free 4880K/5252K, paused 103ms, total 105ms
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=0
wM 是MeasureSpec
的宽度模式,minW 是getSuggestedMinimumWidth()
,ws 是MeasureSpec
的宽度大小。
这同样适用于 hM、minH 和 hs。
我在 table 中 not 覆盖了 onMeasure
(是的,我有,但它只是记录数据并调用 super.onMeasure()
)。 board.onMeasure()
中实现的行为如上所述。
我还在疑惑...
在 kha 的回答后编辑:
kha 的建议奏效了。工作 XML 布局是
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/default_padding"
>
<some.package.Table
android:id="@+id/table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_padding"
android:layout_alignParentBottom="true"
/>
<some.package.Board
android:id="@+id/board"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_above="@id/table"
/>
</RelativeLayout>
日志输出现在是:
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=702
I/Choreographer﹕ Skipped 118 frames! The application may be doing too much work on its main thread.
board: wM=AT_MOST minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=1006
table: wM=EXACTLY minW=0 ws=736 hM=AT_MOST minH=0 hs=1006
board: wM=EXACTLY minW=0 ws=736 hM=EXACTLY minH=0 hs=702
相对布局中视图的顺序决定了它们重叠时的 z 顺序,而不是它们的绘制顺序。此外,权重只对线性布局起作用,对相对布局不起作用。
第二个 XML 几乎是正确的 - 它会测量出 table,让它占用尽可能多的空间,然后在它下面布置电路板。将板的高度更改为 match_parent 它应该可以工作 - 它会强制它占用的空间不超过剩余空间。
试试这个:
移动并更改
android:layout_below="@id/board"
到
android:layout_above="@id/table"
在您的其他布局上。
结合 table 布局上的设置 android:alignParentBottom=true
执行此操作。