【问题标题】:Taming Android ListView Height within a TableRow在 TableRow 中驯服 Android ListView 高度
【发布时间】:2012-03-10 21:13:47
【问题描述】:

n.b.:我打算在 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_1android.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);

不,这也没有帮助。

根据the documentation,我什至给了ListView 正确的ID,因为我想自定义它的布局。当然,我没有使用 ListActivity,所以在这种情况下可能没关系。 (我只是使用常规的 Activity。是的,我也尝试将其更改为 ListActivity。没有骰子。)

不过,我完全可以接受这是飞行员的错误。 (事实上​​,我指望它。)我正处于近视模式变成撞墙模式的地步。 “一定有更好的方法!”

再次请记住,我正在努力保持布局流畅,以便它适用于各种显示器尺寸(不是平板电脑,只是手持设备),因此选择了布局。如果有更好的方法来实现相同的视觉效果,我会全力以赴。

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

感谢线索/答案/指导!

【问题讨论】:

    标签: android android-layout android-listview


    【解决方案1】:

    您的布局存在一些问题,但我没有花很多时间尝试整理您遇到的各种layout_weightlayout_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 的优点。出于某种原因,我无法让该列表正常运行,但是,哇,它就在那里。谢谢吨!
    • 很棒的答案并根据其设计目的适当地嵌套布局。也很好解释。 +1(如果可以的话,+5)
    【解决方案2】:

    原因是布局宽度设置为填充父级 改为使用 wrap content 并在将它们放置在水平线性布局下后为 table 布局和 llistview 分配权重 1

    【讨论】:

    • 是的,我尝试了 wrap_content,但我一定是做错了什么,因为那仍然不起作用。唔。我又试了一次。这一次,在 tableRow4 中,我添加了一个水平 LinearLayout(宽度/高度 = wrap_content),并在其中放置了 listViewSelect、键盘 TableLayout 和 linearLayoutTotal。我还更改了 listViewSelect 以使用 wrap_content 作为宽度/高度,并确保 listViewSelect 和键盘 TableLayout 的权重为 1。(我还将 visibility="gone" 移到了键盘 TableLayout。)当我这样做时,linearLayoutTotal 会填满整个屏幕两个标签除外。
    【解决方案3】:

    乔,

    有许多解决方案可以提供您所寻求的解决方案。查看您的布局后,我想知道您为什么要使用 TableLayout?我的意思是,乍一看,计算器有点像表格。您自己考虑过其他布局解决方案吗?您当然提到其他人还可以,但真正的问题是您如何考虑他们或您对他们了解多少。由于缺乏这方面的信息,我将重点介绍不同类型的布局及其特殊优势。我以这种方式解决它的原因是大多数布局问题都是由于选择了错误的布局类型造成的。

    框架布局

    这个布局对某些人来说很棘手。如果您有多个相同大小的视图,那就太好了。无论大小如何,直接子级的位置始终相同(框架的左上角)。 FrameLayout 的弱点是,如果孩子要同时出现在屏幕上,您必须手动定位它们。许多开发人员(错误地)将它们粘贴在容器中以保持定位。

    线性布局

    使用最频繁的布局之一。如果您具有必须线性增长父级的类似大小的视图,LinearLayouts 特别棒。很多很多新手开发者都使用 LinearLayout 和 layout_weight 来处理所有事情。问题在于,根据 Google 自己的说法,在许多情况下,事情并没有真正线性增长,layout_weight 的效率相对较低。

    相对布局

    一个出色的布局,通过相对定位提供了难以置信的灵活性。定位基于先前声明的视图 ID 或父属性。如果您的定位基于兄弟属性,则最好使用此布局。它也不需要layout_weight,但允许您使用它。这里最重要的是订购。如果您的视图在 XML 中的排序不正确,则它们不会正确呈现或出错。排序取决于哪些视图决定了您的其他属性。

    表格布局

    为您的布局提供类似网格/单元格的结构的布局。它的大小完全取决于父单元,并且在大多数情况下,定位基于前一个单元格。许多开发人员学到的一件事是,隐藏视图和不同大小的单元格可能会很麻烦。这最适合显示数据或其界面。

    现在,为您提供解决方案

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

    2. 鉴于您的特殊要求,我认为 RelativeLayout 是定位的最佳选择。它不需要您使用优化布局和测量通道的layout_weight。它允许您根据其他视图和布局在屏幕上的放置方式来调整大小和位置。你只需要决定你的锚点视图是什么,然后从那里开始。然后你可以用layout_below

    3. 放置你的ListView

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

    希望这会有所帮助, 模糊逻辑

    【讨论】:

    • 首先,关于布局和基本原理的概述写得多么好——谢谢!现在,我为什么要使用 TableLayout?好问题。我最初是从 GridLayout 开始的,但很快就变味了。之后,我简单地尝试了 LinearLayout,阅读了有关性能警告的信息,并迅速转向 RelativeLayout(我同意,这似乎是最明智的选择),但我永远无法让事情在多个分辨率下工作。那时我想:“好吧,这就像表格,虽然它不是数据,但它是按钮”......我最终选择了 TableLayout。就个人而言,我认为我对 TableLayout 的使用更像是一种 hack。
    • 至于 ListView,我也尝试过使用 "invisible""gone",至少对我而言,它没有任何区别。这可能是由于误用,所以我要再试一次。我还要再给RelativeLayout 一个机会。至于"gone" 导致视图丢失其所有布局属性,到目前为止我还没有发现与按钮有关的情况。
    • 至于"gone" 导致视图丢失其所有布局属性,到目前为止,我还没有发现与按钮有关的情况。我在这个例子中没有展示的一件事(为了稍微简化一下)是顶部的一排按钮可能会从两个变为三个甚至一个深度(客户要求)。我没有继续在视图中删除/添加按钮,而是将所有三个按钮都保留在那里,并在每个适当的时间使用"gone"。当我来回更换它们时,它们巧妙地占据了正确的空间。 (也许这是由于其他属性优先。)
    • 好的,现在我来回复您的解决方案!我之前尝试过使用"invisible""gone"。发生的事情相当有趣。回顾一下,我们希望 ListView 和数字键盘 TableLayout 共享相同的空间,但一次只出现一个,对更广泛的布局没有布局副作用,并且无论分辨率如何,都保持一致。这就是发生的事情。 ListView:"gone" 有效,"invisible" 破坏了布局。 TableLayout:"invisible""gone" 效果相同:ListView 展开到 TableView 的顶部,将顶部的所有按钮都抹掉。
    • 请注意,当我说"gone" 适用于 ListView 时,这对于 TableLayout 和按钮来说非常棒,但当鞋子在另一只脚上并且需要在 TableLayout 运行时看到 ListView 时则不然看不见。这留下了RelativeLayout。即便如此,我最后一次尝试使用它时,我也遇到了与那个讨厌的 ListView 完全相同的问题。它似乎只是想填充任何给定容器内可用的所有高度,即使以按钮等其他东西为代价。整个布局必须优雅且一致地填充它所显示的任何屏幕。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多