在TableRow中控制Android ListView的高度

3

注意:我原本想在Pastebin上发布所有这些XML,但我认为将其存档在此处对于后人来说很重要,因此请原谅代码示例的长度!拥有更多信息总比没有好,对吧?

考虑以下类似计算器的布局。(我仅为了本帖硬编码了字符串 - 它们通常是资源。)

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/calculator"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp"
    android:orientation="vertical"
    android:stretchColumns="*">

    <TableRow android:id="@+id/tableRowFieldName"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <TextView android:id="@+id/textViewFieldName"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:layout_marginTop="0dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            android:layout_marginLeft="5dp"
            android:padding="0dp"
            android:text="Label"
            android:textSize="20dp"
            android:textColor="#FFFFFF"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </TableRow>

    <TableRow android:id="@+id/tableRowDisplay"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <TextView android:id="@+id/textViewDisplay"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:layout_margin="5dp"
            android:layout_marginTop="0dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            android:layout_marginLeft="5dp"
            android:padding="0dp"
            android:text="Value"
            android:textSize="35dp"
            android:textColor="#FFFFFF"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </TableRow>

    <TableRow android:id="@+id/tableRow1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0.2">

        <Button android:id="@+id/buttonA"
            style="@style/ParameterButton"
            android:text="Param A" />

        <Button android:id="@+id/buttonB"
            style="@style/ParameterButton"
            android:text="Param B" />
    </TableRow>

    <TableRow android:id="@+id/tableRow2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0.2">

        <Button android:id="@+id/buttonC"
            style="@style/ParameterButton"
            android:text="Param C" />

        <Button android:id="@+id/buttonD"
            style="@style/ParameterButton"
            android:text="Param D" />
    </TableRow>

    <TableRow android:id="@+id/tableRow3"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0.2">

        <Button android:id="@+id/buttonE"
            style="@style/ParameterButton"
            android:text="Param E" />

        <Button android:id="@+id/buttonF"
            style="@style/ParameterButton"
            android:text="Param F" />
    </TableRow>

    <TableRow android:id="@+id/tableRow4"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0.4">

        <ListView android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" 
            android:visibility="gone"
            android:layout_weight="1.0" />

        <TableLayout android:id="@+id/calcKeypad"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:stretchColumns="*">

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button7"
                    style="@style/KeypadButton"
                    android:text="7" />
                <Button android:id="@+id/button8" 
                    style="@style/KeypadButton"
                    android:text="8" />
                <Button android:id="@+id/button9" 
                    style="@style/KeypadButton"
                    android:text="9" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button4"
                    style="@style/KeypadButton"
                    android:text="4" />
                <Button android:id="@+id/button5" 
                    style="@style/KeypadButton"
                    android:text="5" />
                <Button android:id="@+id/button6"
                    style="@style/KeypadButton"
                    android:text="6" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button1"
                    style="@style/KeypadButton"
                    android:text="1" />
                <Button android:id="@+id/button2" 
                    style="@style/KeypadButton"
                    android:text="2" />
                <Button android:id="@+id/button3" 
                    style="@style/KeypadButton"
                    android:text="3" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/buttonClear"
                    style="@style/KeypadButton"
                    android:text="C" />
                <Button android:id="@+id/button0" 
                    style="@style/KeypadButton"
                    android:text="0" />
                <Button android:id="@+id/buttonDecimal" 
                    style="@style/KeypadButton"
                    android:text="." />
            </TableRow>
        </TableLayout>

        <LinearLayout android:id="@+id/linearLayoutTotal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <Button android:id="@+id/buttonTotalWeight"
                style="@style/FunctionButton"
                android:text="Function A" />
            <Button android:id="@+id/buttonTotalCost" 
                style="@style/FunctionButton"
                android:text="Function B" />
            <Button android:id="@+id/buttonAbout" 
                style="@style/FunctionButton"
                android:layout_height="0dp"
                android:layout_weight="0.25"
                android:text="Function C" />
        </LinearLayout>
    </TableRow>
</TableLayout>

这里使用了以下样式(基本上是从原始XML中分离出来的):
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CalcButton">
        <item name="android:textColor">#ffffff</item>
        <item name="android:textSize">15dp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">fill_parent</item>
        <item name="android:layout_margin">2dp</item>
    </style>  
    <style name="ParameterButton" parent="CalcButton">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_weight">0.5</item>
    </style>
    <style name="KeypadButton" parent="CalcButton">
        <item name="android:textSize">20dp</item>
    </style>
    <style name="FunctionButton" parent="CalcButton">
        <item name="android:layout_height">0dp</item>
        <item name="android:layout_weight">0.375</item>
    </style>
</resources>

如果您将所有这些内容放入Android项目中,则应该在顶部看到三行两个参数按钮,下面是数字键盘,数字键盘右侧有三个功能按钮。大多数情况下都是无害的。(此外,它只会在纵向使用,因此不必担心考虑横向。)
然而...请特别注意XML中的ListView。您目前还看不到它,因为它具有android:visibility="gone"。想法是,在某些时候,我会将其删除,然后将数字键盘(相邻的TableLayout)设置为android:visibility="gone",从而显示列表。
换句话说,期望的效果是使列表和数字键盘占用完全相同的空间,以便我可以随意在两者之间切换。
我的问题是,一旦填充了ListView,它似乎打算占用整个表格的高度,摧毁可怜的参数按钮并将三个功能按钮带上路。
您可以通过设置一个非常基本的ArrayAdapter(我使用了android.R.layout.simple_list_item_1和android.R.id.text1)并将一个简单的String数组传递给它来看到这一点。目前,手动将“gone”赋值从列表移动到相邻的表格布局中(或在代码中执行此操作)。
设置固定高度似乎不可行,因为这应该在各种显示屏上工作。实际上,我甚至尝试了一个也许是错误的努力:
ListView list = (ListView) findViewById(android.R.id.list);
TableLayout calcKeypad = (TableLayout) findViewById(R.id.calcKeypad);

list.layout(calcKeypad.getLeft(), calcKeypad.getTop(), calcKeypad.getRight(), calcKeypad.getBottom());
calcKeypad.setVisibility(View.GONE);
list.setVisibility(View.VISIBLE);

不行,那也没帮助。

按照文档的要求,我甚至给ListView赋予了正确的ID,因为我想自定义它的布局。当然,我没有使用ListActivity,所以在这种情况下可能并不重要。(我只是使用普通的Activity。是的,我也尝试将其更改为ListActivity。但是都不行。)

不过,我完全可以接受这是我的错误。(事实上,我就指望着这个。) 我已经到了头撞墙的地步了。“一定有更好的方法!”

再次强调,我正在努力保持布局的流动性,以便在各种显示器尺寸(不是平板电脑,只是手持设备)上能够很好地工作,因此选择了这种布局。如果有更好的方法可以实现相同的效果,我非常乐意倾听。

底线:如何使ListView仅占用相邻计算器键盘(TableLayout)占用的区域?

欢迎提供提示/答案/指导!

3个回答

2

您的布局存在一些问题,但我没有花太多时间来解决您的各种 layout_weight 和 layout_height 的情况。我认为您也许能够使其正常工作,但我采用了一个稍微不同的方法。

我将布局分成了三个底部元素之上的一系列行。简单来说,您有:

TextView-------------------------------
TextView-------------------------------
LinearLayout---------------------------
LinearLayout---------------------------
LinearLayout---------------------------
---------------------------------------
TableLayout and ListView | LinearLayout

我并不是说这是最有效的布局方法,但每个布局元素都有其作用,因此您可能需要付出一些努力来将它们替换为更高效的元素。

特别地,对于您的参数按钮和函数按钮,使用 LinearLayout 可以很好地利用 layout_weight 特性。其他非 LinearLayout 的布局中没有该特性(您可能不知道的是,TableRowLinearLayout 的子类,这就是为什么 layout_weight 在其中可用而在 RelativeLayout 中不可用),而根据百分比划分可用空间似乎适用于这些元素。

包含数字按钮的 TableLayout 可能可以被替换,但它很好地为不同大小的视图分配按钮空间,并且还很好地分隔行以填充可用空间。同样,这可能很难被替换。

我所做的是用适当的对齐属性将您的总体 TableLayout 替换为一个 RelativeLayout。这使得您可以将函数按钮 LinearLayout 放在右边框上,并使 ListViewTableLayout 占据参数按钮下方和函数按钮左侧的剩余空间。我并不是说您一定要这样做,但它比您原始设计中多出了一些布局元素,并且可以完成您所寻找的工作。

这是我所做的情况说明。请注意,我在您的 ParameterButton 样式中添加了 layout_heightwrap_content。此外,此布局中显示了 ListViewTableLayout。您可能需要在布局或代码中进行调整。

样式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CalcButton">
        <item name="android:textColor">#ffffff</item>
        <item name="android:textSize">15dp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">fill_parent</item>
        <item name="android:layout_margin">2dp</item>
    </style>  
    <style name="ParameterButton" parent="CalcButton">
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_weight">0.5</item>
    </style>
    <style name="KeypadButton" parent="CalcButton">
        <item name="android:textSize">20dp</item>
    </style>
    <style name="FunctionButton" parent="CalcButton">
        <item name="android:layout_height">0dp</item>
        <item name="android:layout_weight">0.375</item>
    </style>
</resources>

布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/calculator"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp"
    android:orientation="vertical"
    android:stretchColumns="*">
        <TextView android:id="@+id/textViewFieldName"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:layout_marginTop="0dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            android:layout_marginLeft="5dp"
            android:padding="0dp"
            android:text="Label"
            android:textSize="20dp"
            android:textColor="#FFFFFF"
            android:textAppearance="?android:attr/textAppearanceMedium" />
        <TextView android:id="@+id/textViewDisplay"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:layout_margin="5dp"
            android:layout_marginTop="0dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="0dp"
            android:layout_marginLeft="5dp"
            android:padding="0dp"
            android:layout_below="@id/textViewFieldName"
            android:text="Value"
            android:textSize="35dp"
            android:textColor="#FFFFFF"
            android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout android:id="@+id/tableRow1"
        android:layout_below="@id/textViewDisplay"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/buttonA"
            style="@style/ParameterButton"
            android:layout_height="wrap_content"
            android:text="Param A" />
        <Button android:id="@+id/buttonB"
            style="@style/ParameterButton"
            android:text="Param B" />
    </LinearLayout>

    <LinearLayout android:id="@+id/tableRow2"
        android:layout_below="@id/tableRow1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/buttonC"
            style="@style/ParameterButton"
            android:text="Param C" />
        <Button android:id="@+id/buttonD"
            style="@style/ParameterButton"
            android:text="Param D" />
    </LinearLayout>

    <LinearLayout android:id="@+id/tableRow3"
        android:layout_below="@id/tableRow2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/buttonE"
            style="@style/ParameterButton"
            android:text="Param E" />
        <Button android:id="@+id/buttonF"
            style="@style/ParameterButton"
            android:text="Param F" />
    </LinearLayout>



        <ListView android:id="@android:id/list"
            android:layout_below="@id/tableRow3"
            android:layout_toLeftOf="@+id/linearLayoutTotal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <TableLayout android:id="@+id/calcKeypad"
            android:layout_below="@id/tableRow3"
            android:layout_toLeftOf="@id/linearLayoutTotal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:stretchColumns="*">

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button7"
                    style="@style/KeypadButton"
                    android:text="7" />
                <Button android:id="@+id/button8" 
                    style="@style/KeypadButton"
                    android:text="8" />
                <Button android:id="@+id/button9" 
                    style="@style/KeypadButton"
                    android:text="9" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button4"
                    style="@style/KeypadButton"
                    android:text="4" />
                <Button android:id="@+id/button5" 
                    style="@style/KeypadButton"
                    android:text="5" />
                <Button android:id="@+id/button6"
                    style="@style/KeypadButton"
                    android:text="6" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/button1"
                    style="@style/KeypadButton"
                    android:text="1" />
                <Button android:id="@+id/button2" 
                    style="@style/KeypadButton"
                    android:text="2" />
                <Button android:id="@+id/button3" 
                    style="@style/KeypadButton"
                    android:text="3" />
            </TableRow>

            <TableRow
                android:layout_weight="0.25"
                android:gravity="center">
                <Button android:id="@+id/buttonClear"
                    style="@style/KeypadButton"
                    android:text="C" />
                <Button android:id="@+id/button0" 
                    style="@style/KeypadButton"
                    android:text="0" />
                <Button android:id="@+id/buttonDecimal" 
                    style="@style/KeypadButton"
                    android:text="." />
            </TableRow>
        </TableLayout>

    <LinearLayout android:id="@id/linearLayoutTotal"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_below="@id/tableRow3"
        android:layout_alignParentRight="true"
        android:orientation="vertical">

        <Button android:id="@+id/buttonTotalWeight"
            style="@style/FunctionButton"
            android:text="Function A" />
        <Button android:id="@+id/buttonTotalCost" 
            style="@style/FunctionButton"
            android:text="Function B" />
        <Button android:id="@+id/buttonAbout" 
            style="@style/FunctionButton"
            android:layout_height="0dp"
            android:layout_weight="0.25"
            android:text="Function C" />
    </LinearLayout>

</RelativeLayout>

哦。我的天啊。你做到了。这将TableLayout和RelativeLayout的最佳部分融合在一起。出于某种原因,我无法让那个列表表现良好,但是,哇,它在那里。非常感谢! - Joe D'Andrea
1
很棒的答案,并根据其设计目的适当嵌套布局。解释得也很清晰。+1(如果可以,+5)。 - Fuzzical Logic

1

乔:

有很多解决方案可以提供你所需的解决方案。看了一下你的布局,我不知道为什么你要使用TableLayout?我是说,第一眼看起来,计算器就像是一个表格,有点类似。你是否考虑过其他布局方案?你肯定提到了其他布局方案,但真正的问题是你如何考虑他们或者你对他们了解多少。由于缺乏相关信息,我将重点介绍不同类型的布局及其特点。我以这种方式进行介绍的原因是大多数布局问题都源自于选择错误的布局类型。

FrameLayout

对某些人来说,这个布局比较棘手。如果你有多个大小相同的视图,那么它非常适用。紧挨着的子元素的位置始终相同(位于Frame的左上角),而不受大小的影响。 FrameLayout 的弱点在于,如果它们要同时显示在屏幕上,则必须手动定位子元素。许多开发人员(错误地)将它们放入容器中以保持位置。

LinearLayout

最为常用的布局之一。LinearLayout特别适合需要根据父布局线性增长的大小相同的视图。但是,许多初学者开发人员会把LinearLayout和layout_weight用于所有布局。问题在于,很多情况下,事物并不是真正线性增长的,而且根据谷歌本身的说法,layout_weight相对效率较低。

RelativeLayout

一个优秀的布局,提供了相对位置灵活性。定位基于先前声明的视图ID或父属性。如果您的定位基于兄弟属性,则最好使用此布局。它也不需要layout_weight,但允许您利用它。最重要的是排序。如果您的视图在XML中未正确排序,则无法正确呈现或出现错误。排序由哪些视图确定其他属性来确定。

TableLayout

为您的布局提供网格/单元格结构的布局。其大小完全取决于父级,并且在大多数情况下,定位是基于上一个单元格的。许多开发人员已经学到了一个问题:它可能与隐藏视图和不同大小的单元格有关。这是显示数据或其接口的最佳方式。

现在,为您提供解决方案

  1. 如果您仍然想使用TableLayout,请将ListView的可见性设置为"invisible"而不是"gone"。这两者之间的区别微妙但重要。"invisible"表示它仍然占用布局,即使它不可见。"gone"表示它失去了所有的布局属性,当您显示对象时必须手动设置。

  2. 根据您的特定要求,我认为RelativeLayout是最适合定位的。它不需要您使用layout_weight来优化布局和测量传递。它允许您根据屏幕上放置其他视图和布局的方式来调整大小和位置。您只需决定您的锚点视图并从那里开始。然后您可以使用layout_below放置您的ListView。

如果您需要有关这些布局的更多信息,我很乐意为您提供官方来源的链接。

希望这可以帮助您, FuzzicalLogic


首先,布局和理念方面的概述写得非常好 - 谢谢!那么,我为什么要使用TableLayout呢?好问题。我最初使用的是GridLayout,但很快就出了问题。之后,我尝试了LinearLayout,但很快就读到了性能警告,并迅速转向RelativeLayout(我同意,这似乎是最明智的选择),但我无法在多个分辨率下使其正常工作。那时,我想:“嗯,这很像表格,虽然不是数据,而是按钮”...于是我最终选择了TableLayout。就我个人而言,我认为我使用TableLayout更像是一种hack。 - Joe D'Andrea
关于ListView,我也尝试过使用 "invisible""gone",但至少对我来说没有任何区别。这可能是由于误用的原因,所以我打算再次尝试。我还打算重新使用RelativeLayout。至于使用 "gone" 导致视图丢失所有布局属性,到目前为止,就按钮而言,我还没有发现这种情况。 - Joe D'Andrea
至于“gone”导致视图失去其所有布局属性,就目前而言我还没有发现这种情况会影响到按钮。在这个例子中,我并没有展示出一个问题(为了简化点),顶部的一个按钮行可能从两个变成三个或者变成一个(根据客户要求)。与其不断地从视图中添加/移除按钮,我将所有三个按钮都保留在那里,并在每个按钮上适当时使用"gone"。当我来回切换它们时,它们会整洁地占用正确的空间。(也许这是由于其他优先级更高的属性所导致的。) - Joe D'Andrea
好的,现在是我对你的解决方案的回应!我之前尝试过使用 "invisible""gone"。发生的事情非常有趣。回顾一下,我们希望 ListView 和数字键盘 TableLayout 共享同一空间,但每次只显示一个,不会对整体布局产生任何副作用,并且无论分辨率如何都保持一致。这里发生了什么。ListView:"gone" 可以正常工作,而 "invisible" 会破坏布局。TableLayout:"invisible""gone" 有相同的效果:ListView 扩展到 TableView 的顶部,摧毁了所有上面的按钮。 - Joe D'Andrea
请注意,当我说“gone”适用于ListView时,这对于TableLayout和按钮来说非常好,但是当ListView需要在TableLayout不可见时显示出来时,情况就不同了。这时候只能使用RelativeLayout。即使如此,上次我尝试使用它时,我遇到了与那个讨厌的ListView完全相同的问题。它似乎只想填充任何给定容器中可用的所有高度,即使以牺牲其他东西(如按钮)为代价。整个布局必须优雅而一致地填充显示屏幕。 - Joe D'Andrea
显示剩余3条评论

1
原因是布局宽度被设置为填充父级,应该改用包裹内容,并在将它们放置在水平线性布局下后,为表格布局和列表视图分配权重1。

是的,我尝试了wrap_content,但我一定做错了什么,因为那还是不起作用。嗯。我再试一次。这次,在tableRow4内部,我添加了一个水平LinearLayout(宽度/高度=wrap_content),并在其中放置了listViewSelect、键盘TableLayout和linearLayoutTotal。我还将listViewSelect更改为使用wrap_content作为宽度/高度,并确保listViewSelect和键盘TableLayout的权重为1。(我还将visibility="gone"移到了键盘TableLayout上。)当我这样做时,除了两个标签之外,linearLayoutTotal填满整个屏幕。 - Joe D'Andrea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接