Android:如何使自定义视图仅占用可用的屏幕空间?

时间:2015-03-05 21:33:16

标签: android android-layout

我有两个自定义视图,我想垂直布局。 第一种观点是一种游戏板,它是一个正方形。方块很容易缩放,几乎可以适应任何可用的空间。

第二个视图是[TableLayout][1]的子类,它包含多个Button个。行/列的数量在运行时确定。

为了便于解释,我将调用第一个视图 board 和第二个 table

我希望 board 显示在屏幕顶部, table 应该在它下面。 应该占用它所需的垂直空间(这主要取决于行数)。 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>

通过这种方法,我希望首先测量,并将剩余的可用屏幕高度作为最大值(即AT_MOST)高度规格传递给{{1} board 。这个假设似乎是错误的。

当我使用这种布局时,电路板似乎被调整为零尺寸,即它不会被渲染。

当我转过身时:

onMeasure

board 占用太多垂直空间,在底部被切断

在这两种情况下, board 将显示宽度设为<?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> 宽度规格,将显示高度(减去状态栏和操作栏高度)设为AT_MOST高度规范。因此,我的AT_MOST实现将两者的最小值视为方形大小,这不会为表视图留下足够的空间。

有人可以告诉我如何解决这个问题吗? 我可能需要添加嵌套布局吗?或者使用布局权重? - 我没有这样做,因为权重是我理解中的相对大小。

谢谢&amp;亲切的问候


在Gabe的回答后编辑:

在尝试了Gabe的建议后,我在 board table onMeasure方法中记录了一些数据:

onMeasure

wM是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 的宽度模式,minW是MeasureSpec,ws是getSuggestedMinimumWidth()的宽度尺寸。 同样适用于hM,minH和hs。

我在重写了MeasureSpec(是的,我有,但它只记录数据并调用onMeasure)。 super.onMeasure()中实现的行为如上所述。

我仍然感到困惑......


按照kha的回答编辑:

kha的建议奏效了。工作的XML布局是

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.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>

2 个答案:

答案 0 :(得分:1)

试试这个:

移动并更改

android:layout_below="@id/board" 

android:layout_above="@id/table" 

在您的其他布局上。

与您在桌面布局上设置android:alignParentBottom=true一起执行此操作。

答案 1 :(得分:0)

相对布局中的视图顺序决定了z排序是否重叠,而不是它们被绘制的顺序。另外,权重只对LinearLayout而不是相对做。

第二个XML几乎是正确的 - 它将测量出表格,让它占用尽可能多的空间,然后在它下面布置板子。将电路板的高度更改为match_parent并且它应该工作 - 它将强制它占用不超过剩余的房间。