Taming the height of a ListView in a TableRow

nb: I was going to publish all this XML on Pastebin, but I think it is important that it be archived here for posterity, so please read the length of the code sample! It's better to have more information than less, right?

Consider the following calculator layout. (I hardcoded the strings just for this post - they are usually resources.)

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

      

The following styles are used here (essentially from the original 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>

      

If you have to throw all of this into an Android project, you should see three lines of two option buttons up, followed by a numeric keypad below, with three function buttons to the right of the keyboard. In most cases it is harmless. (Plus, it will only be used in portraiture, so you don't have to worry about taking into account the landscape.)

However ... pay special attention to the ListView in XML. You won't see it visually yet, as it has android:visibility="gone"

. The idea is that at certain points I will remove this and then set the numeric keypad (adjacent TableLayout ) instead android:visibility="gone"

, thus showing the list in its place.

In other words, the desired effect is to have the list box and the numeric keypad occupy exactly the same space so that I can flip between them at will.

The problem I'm running into is that the ListView , once full, seems to intend to tackle the entire height of the overall table, erase buttons with unsatisfactory options, and bring the three function buttons closer for the ride.

You can see this by linking a very simple ArrayAdapter (I used android.R.layout.simple_list_item_1

and android.R.id.text1

) and dumping the rudimentary array String

. For now, manually move the assignment gone

from the list to the adjacent table layout (or do it in code).

Setting a fixed height seems out of the question as this should work on different displays. In fact, I even tried, perhaps with the wrong deed:

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);

      

No, that didn't help either.

As per the documentation, I even gave the ListView the correct ID, as I want to customize its layout. Of course, I'm not using ListActivity , so maybe it doesn't matter in this case. (I'm just using regular activity . Yes, I tried changing that to ListActivity . No dice.)

Nevertheless, I am fully prepared for the fact that this is a pilot error. (Actually, I'm counting on it.) I'm just at the point where it becomes the dizziness mode in the wall in myopia. "There must be a better way!"

Again, keep in mind, I try very hard to maintain the layout so that it works well on different display sizes (not tablets, just PDAs) hence the chosen layout. If there is a better way that performs the same visual, I'm all ears.

Bottom line: How to make the ListView occupy only the area occupied by this adjacent calculator keyboard ( TableLayout )?

Hints / Answers / Recommendations Appreciated!

+3


source to share


3 answers


There are some issues with your layout, but I haven't spent a lot of time trying to figure out the different situations layout_weight

and layout_height

that you have. I think you could get this to work, but I took a slightly different approach.

I broke the layout in a row of rows over the three elements at the bottom. Basically you have:

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

      

I'm not saying this is the most efficient layout, but every element of the layout has a job, so you might have to go a few lengths to replace them with something more efficient.

In particular, using LinearLayout

options and function buttons for your buttons makes good use of the function layout_weight

. It is not available in other layouts that are not subclasses LinearLayout

(you may not know what TableRow

is subclassing LinearLayout

and therefore layout_weight

works there but not in RelativeLayout

), and the ability to split the available space on a percentage basis seems appropriate for these elements.

The TableLayout with number buttons might be replaced, but it does a good job of allocating space for buttons at different sizes and also does a good job of making the rows fill the available space. Again, this can be difficult to replace.



What I did was replace your general TableLayout

with the RelativeLayout

appropriate alignment attributes. This allows the function button to be placed LinearLayout

on the right border while ListView

or to TableLayout

consume the remaining space below the parameter buttons and to the left of the function buttons. I'm not saying you need to do this, necessarily, but it saves some extra layout elements over your original design and gets the job you're looking for.

Here is the work on what I did. Note that I added layout_height

of wrap_content

to your ParameterButton style. In addition, both ListView

and are visible in this layout TableLayout

. You may need to customize your layout or code.

Style:

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

      

Layout:

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

      

+2


source


The reason is that the layout width is set as padding parent instead use wrapper content instead and give weight 1 to both table layout and llistview after placing them in a horizontal linear layout



+1


source


Joe,

There are a number of solutions that can provide the solution you are looking for. After looking at your layout, I'm left wondering why are you using TableLayout? I mean, at first glance, a calculator looks like a table, sort of. Have you considered other Layout solutions yourself? You are of course saying the others are ok, but the real question is how you viewed them or what you know about them. Due to the lack of information in this regard, I'm going to highlight the different types of layouts and their particular strengths. The reason I refer to it this way is because most layout problems arise from choosing the wrong layout type.

FrameLayout

This layout is tricky for some. It's great if you have several species of the same size. The positioning of immediate children is always the same (top left of the frame), regardless of size. The weakness of FrameLayout is that you have to manually place the children if they are to be displayed on the screen at the same time. Many developers (inappropriately) attach them inside a container to maintain positioning.

LinearLayout

One of the most commonly used layouts. LinearLayouts are especially awesome if you have similar dimensions that are supposed to grow linearly by their parents. Many aspiring developers use LinearLayout layout_weight

for everything. The problem is that in many cases the situation does not grow linearly, but layout_weight

rather ineffectively, according to Google itself.

RelativeLayout

Great layout that offers incredible flexibility in relative positioning. Positioning is based on previously declared view IDs or parent attributes. If your positioning is based on affinity properties, this layout is best used. It also doesn't require layout_weight

but allows you to use it. The most important thing is to order here. If your views are not ordered correctly in your XML, they are not rendered correctly or are not rendered. The order is determined by which views define your other properties.

TableLayout

A layout that provides a grid / cell structure suitable for your layouts. Its size is entirely dependent on the parent, and positioning in most cases is based on the previous cell. One of the things many developers teach is that it can be frustrating with hidden views and cells of different sizes. It is best to display data or their interfaces.

Now for your decisions

  • If you still love using TableLayout, set your ListView's visibility to "invisible"

    , not "gone"

    . The difference between the two is subtle but important. "invisible"

    means it still occupies the layout even though it is not displayed. "gone"

    means it loses all of its layout properties and must be set manually when you show the object.

  • Given your special requirements, I think RelativeLayout will be optimal for positioning. It requires no use layout_weight

    , which optimizes the layout and measures the passed values. And it allows you to size and position according to how other views and layouts are positioned on the screen. You just need to decide what your anchor views are and start there. Then you can host your ListView withlayout_below

If you need more information on any of these layouts, I will happily provide you with links to the official sources.

Hope this helps, FuzzicalLogic

+1


source







All Articles