Укрощение Android ListView Высота внутри TableRow - PullRequest
3 голосов
/ 11 марта 2012

n.b .: Я собирался опубликовать весь этот XML на Pastebin, но я думаю, что важно заархивировать его здесь для потомков, поэтому, пожалуйста, извините за длину примера кода! Лучше иметь больше информации, чем меньше, верно?

Рассмотрим следующую схему калькулятора. (Я жестко запрограммировал строки только для этого поста - они обычно являются ресурсами.)

<?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, вы должны увидеть три ряда кнопок с двумя параметрами вверху, за которыми следует цифровая клавиатура с тремя функциональными кнопками справа от клавиатуры. В большинстве случаев безвредна. (Кроме того, он будет использоваться только в портретной ориентации - поэтому не стоит беспокоиться о том, чтобы учитывать ландшафт).

Однако ... обратите особое внимание на ListView в XML. Вы пока не увидите его в визуальном виде, поскольку он имеет 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 правильный идентификатор, так как я хочу настроить его макет. Конечно, я не использую ListActivity , поэтому, возможно, это не имеет значения в этом случае. (Я просто использую обычную активность . Да, я пытался изменить это значение на ListActivity тоже. Никаких кубиков.)

Тем не менее, я полностью открыт для этой ошибки пилота. (На самом деле, я рассчитываю на это.) Я как раз в тот момент, когда он стал «бить головой о стену в миопии». «Должен быть лучший способ!»

Опять-таки, имейте в виду, что я очень стараюсь сохранить раскладку, чтобы она хорошо работала на экранах разных размеров (не на планшетах, а на портативных устройствах), отсюда и выбранная раскладка. Если есть лучший способ добиться того же визуального эффекта, я весь слух.

Итог: как сделать так, чтобы ListView занимал только область, занятую соседней клавиатурой калькулятора ( TableLayout )?

Подсказки / ответы / рекомендации приветствуются!

Ответы [ 3 ]

2 голосов
/ 21 марта 2012

В вашем макете есть некоторые проблемы, но я не тратил много времени, пытаясь разобраться в различных ситуациях layout_weight и layout_height, которые у вас есть.Я думаю, вы могли бы заставить это работать, но я выбрал немного другой подход.

Я разбил макет на ряд строк над тремя элементами внизу.По сути, у вас есть:

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

Я не говорю, что это самый эффективный макет, но у каждого элемента макета есть работа, поэтому вам, возможно, придется пойти на некоторые шаги, чтобы заменить их чем-то более эффективным.

В частности, использование LinearLayout для кнопок параметров и функциональных кнопок позволяет использовать функцию layout_weight.Он недоступен в других макетах, которые не являются подклассами LinearLayout (вы можете не знать, что TableRow является подклассом LinearLayout, и именно поэтому layout_weight работает там, но не в RelativeLayout) и способностьюразделение доступного пространства в процентном отношении представляется подходящим для этих элементов.

TableLayout, содержащий цифровые кнопки, возможно, можно заменить, но он хорошо справляется с распределением пространства для кнопок в представлениях разных размеров,и это также делает хорошую работу по расстановке строк, чтобы заполнить доступное пространство.Опять же, это может быть сложно заменить.

То, что я сделал, это заменил ваш общий TableLayout на RelativeLayout с соответствующими атрибутами выравнивания.Это позволяет вам поместить функциональную кнопку LinearLayout напротив правой границы, а ListView или TableLayout занять оставшееся пространство под кнопками параметров и слева от функциональных кнопок.Я не говорю, что вы должны делать это обязательно, но это сохраняет некоторые дополнительные элементы макета поверх вашего оригинального дизайна и выполняет работу, которую вы ищете.

Вот пример того, что я сделал.Обратите внимание, что я добавил layout_height из wrap_content к вашему стилю ParameterButton.Кроме того, в этом макете видны как ListView, так и TableLayout.Вы можете настроить в макете или в вашем коде.

Стиль:

<?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>
1 голос
/ 20 марта 2012

Джо,

Существует ряд решений, которые могут предоставить решение, которое вы ищете.Посмотрев на ваш макет, мне остается задуматься, почему вы используете TableLayout?Я имею в виду, на первый взгляд, калькулятор похож на Таблицу.Рассматривали ли вы другие макеты самостоятельно?Вы, конечно, упоминаете, что с другими все в порядке, но реальный вопрос в том, как вы их рассмотрели или что вы о них знаете.Из-за нехватки информации в этом отношении я собираюсь выделить различные виды макетов и их конкретные преимущества.Причина, по которой я обращаюсь к нему таким образом, заключается в том, что большинство проблем с макетом возникает в результате выбора неправильного типа макета.

FrameLayout

Этот макет сложен для некоторых.Это хорошо, если у вас есть несколько видов, которые имеют одинаковый размер.Расположение ближайших потомков всегда одинаково (вверху слева от кадра), независимо от размера.Слабость FrameLayout заключается в том, что вы должны вручную расположить дочерние элементы, если они будут одновременно на экране.Многие разработчики (ошибочно) помещают их в контейнер, чтобы сохранить позиционирование.

LinearLayout

Один из наиболее часто используемых макетов.LinearLayouts особенно хороши, если у вас есть представления одинакового размера, которые должны линейно увеличивать родительский вид.Многие, многие начинающие разработчики используют LinearLayout и layout_weight для всего.Проблема в том, что во многих случаях, по словам самого Google, во многих случаях линейный рост не происходит, и layout_weight относительно неэффективен.

RelativeLayout

Отличный макетэто предлагает невероятную гибкость с относительным позиционированием.Позиционирование основано на ранее объявленных идентификаторах вида или родительских атрибутах.Если ваше позиционирование основано на свойствах братьев и сестер, этот макет лучше всего использовать.Он также не требует layout_weight, но позволяет использовать его.Самое главное здесь это заказ.Если ваши представления не упорядочены правильно в вашем XML, они не отображаются правильно или выдают ошибку.Порядок определяется тем, какие виды определяют другие ваши свойства.

TableLayout

Макет, обеспечивающий структуру в виде сетки / ячейки для ваших макетов.Его размер полностью зависит от родителя, а расположение в большинстве случаев основано на предыдущей ячейке.Одна из вещей, которую изучают многие разработчики, это то, что это может быть неприятно со скрытыми представлениями и ячейками разных размеров.Это лучше всего подходит для отображения данных или их интерфейсов.

Теперь для ваших решений

  1. Если вы все еще заинтересованы в использовании TableLayout, установитевидимость вашего ListView до "invisible", а не "gone".Разница между этими двумя тонкая, но важная."invisible" означает, что он по-прежнему занимает макет, даже если он не виден."gone" означает, что он теряет все свои свойства макета, и они должны быть установлены вручную, когда вы показываете объект.

  2. Учитывая ваши конкретные требования, я думаю, что RelativeLayout будет оптимальным для позиционирования,Вам не нужно использовать layout_weight, который оптимизирует макет и измеряет проходы.И это позволяет вам изменять размер и положение в соответствии с тем, как другие виды и макеты размещаются на экране.Вы просто должны решить, каковы ваши якорные взгляды и начать там.Затем вы можете разместить свой ListView с layout_below

Если вам нужна дополнительная информация о любом из этих макетов, я с удовольствием предоставлю вам ссылки на официальные источники.

Надеюсь, это поможет, FuzzicalLogic

1 голос
/ 16 марта 2012

Причина в том, что для ширины макета задано заполнение родительского элемента, вместо этого используйте содержимое переноса и присвойте вес 1 как макету таблицы, так и просмотру списка после помещения их в горизонтальный линейный макет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...