【问题标题】:Android: How to make a custom view take only the available screen space?Android:如何让自定义视图只占用可用的屏幕空间?
【发布时间】:2015-03-05 21:33:15
【问题描述】:

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

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

为了便于解释,我将调用第一个视图 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)高度规范传递给 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占用了太多垂直空间,table底部被截断

在这两种情况下,board 将显示宽度设为AT_MOST 宽度规格,将显示高度(减去状态栏和操作栏高度)设为AT_MOST 高度规格。所以我的onMeasure 实现将两者中的最小值作为正方形大小,这没有为表格视图留下足够的空间。

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

感谢和问候


在 Gabe 回答后编辑:

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

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

【问题讨论】:

  • 只是一个想法(我现在无法访问 Android,所以这都是猜测)但是如果您在其他布局上移动并将 android:layout_below="@id/board" 更改为 android:layout_above="@id/table" 会发生什么。结合在表格布局上设置android:alignParentBottom=true 执行此操作。没有日食很难提供帮助,但如果你幸运的话,这可能会起作用:)。
  • 这是一个可行的解决方案。如果您将此作为答案发布,我会将其标记为正确。非常感谢:-)
  • 只是一个猜测,所以我很高兴它确实有效:)。我会把它作为答案发布。

标签: android android-layout


【解决方案1】:

试试这个:

移动和改变

android:layout_below="@id/board" 

android:layout_above="@id/table" 

在您的其他布局上。

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

【讨论】:

    【解决方案2】:

    相对布局中视图的顺序决定了它们重叠时的 z 顺序,而不是它们的绘制顺序。此外,权重仅对 LinearLayout 起作用,而不是相对。

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

    【讨论】:

    • 感谢您的快速回复,但遗憾的是,这不是解决方案。
    • 过去就是这样做的。除非您的 onMeasure 正在做一些奇怪的事情,否则它应该可以工作。
    • 嗨 Gabe,我将编辑我的原始问题以包括测量过程的日志记录输出。
    猜你喜欢
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多