2-колоночный TableLayout с 50% точно для каждого столбца

Это озадачивает меня с момента моих первых шагов с Android. Я не могу сделать оба столбца в 2-столбцовом TableLayout точно на 50% каждый.

Вот пример:

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" >

    <TableLayout
        android:id="@+id/tablelayout"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:paddingRight="2dip" >

        <TableRow>
            <TextView
                style="@style/TextViewStandard"
                android_layout_span="2"
                android:layout_weight="1" 
                android:text="Bla" />
        </TableRow>

        <TableRow>
            <TextView
                style="@style/TextViewStandard"
                android:layout_weight="1"
                android:text="Name:" />

            <EditText
                style="@style/EditTextStandard"
                android:id="@+id/et_name"
                android:layout_weight="1" />
        </TableRow>

        <TableRow>
            <TextView
                style="@style/TextViewStandard"
                android:layout_weight="1"
                android:text="URL:" />

            <EditText
                style="@style/EditTextStandard"
                android:id="@+id/et_url"
                android:layout_weight="1" />
        </TableRow>

        <TableRow>
            <Button
                style="@style/ButtonStandard"
                android:layout_column="0"
                android:layout_marginTop="6dip"
                android:onClick="onClickOk"
                android:text="@android:string/ok" />
        </TableRow>
    </TableLayout>
</ScrollView>

А вот соответствующее определение стиля:

<resources>
    <style name="ButtonStandard" parent="@android:style/Widget.Button">
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">fill_parent</item>
    </style>

    <style name="EditTextStandard" parent="@android:style/Widget.EditText">
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_marginLeft">2dip</item>
        <item name="android:layout_marginRight">2dip</item>
        <item name="android:layout_marginTop">2dip</item>
        <item name="android:layout_width">fill_parent</item>
    </style>

    <style name="TextViewStandard" parent="@android:style/Widget.TextView">
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_marginLeft">2dip</item>
        <item name="android:layout_marginRight">2dip</item>
        <item name="android:layout_marginTop">2dip</item>
        <item name="android:layout_width">fill_parent</item>
        <item name="android:textColor">@android:color/white</item>
    </style>
</resources>

Это становится действительно испорченным с включенным CheckBox.

Что не так с моим определением?

Спасибо заранее. HJW


person Harald Wilhelm    schedule 18.01.2011    source источник


Ответы (4)


Вы пытались установить для атрибута android:layout_width значение 0dp (и, конечно, сохранить android:layout_weight как 1) в дочерних представлениях?

Я был в подобных сценариях, когда я также хотел распределить заданное пространство поровну между двумя дочерними представлениями, но не смог этого сделать, поскольку дочерний элемент с «более широким содержимым» также стал шире внутри своего родителя, чем его родной брат. Это было связано с тем, что более широкий ребенок имел большую начальную ширину. Убедившись, что оба дочерних элемента начинаются с одинаковой ширины (android:layout_width="0dp" на обоих из них), также гарантируется равномерное распределение пространства между ними.

person dbm    schedule 18.01.2011
comment
Что еще более важно, если вы сделаете это, сбросьте TableLayout и переключитесь на LinearLayout. TableLayout предназначен для случаев, когда вам нужно, чтобы Android вычислял ширину столбцов на основе содержимого ячеек. Если вы намеренно игнорируете это, вы можете вместо этого использовать вложенный LinearLayouts. - person CommonsWare; 18.01.2011
comment
@ChristianB: Спасибо за объяснение. Я всегда думал, что с TableLayout должно быть что-то не так. Интересно, что многие неудачные TableLayouts отлично работают с эмулятором 2.3. @dbm: если для layout_width установлено значение 0dp, все дочерние представления (TextView/EditText) исчезли. Спасибо, в любом случае. Я проверю решение CommonsWares и полностью откажусь от TableLayouts. Не знаю, для чего они хороши, если вам нужно знать, что в них может быть напечатано и может их испортить... - person Harald Wilhelm; 18.01.2011
comment
@CommonsWare: Не могу поверить, почему я взял TableLayouts? Изменение их на LinearLayout сработало идеально. Большое Вам спасибо. - person Harald Wilhelm; 18.01.2011

Вот как я равномерно форматирую свои таблицы. Не является частью вашего вопроса, но охватывает все столбцы android:layout_span="2" других дочерних элементов TableRow, которые не содержат атрибута android:layout_column. Надеюсь это поможет.

<TableLayout 
  android:id="@+id/tableLayout1"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:stretchColumns="0,1">

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

        <TextView
          android:id="@+id/textView1"
          android:layout_column="0">
        </TextView>

        <TextView
          android:id="@+id/textView2"
          android:layout_column="1">
        </TextView>

    </TableRow>

</TableLayout> 
person outkkast    schedule 17.04.2012
comment
android:stretchColumns=0,1 в этом случае можно заменить просто android:stretchColumns=* - person Fran Marzoa; 19.02.2020

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

    <TableLayout 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1">

        <TableRow>
            <FrameLayout 
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1">

                <ImageView android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:src="@drawable/button_wedding_day_cheat_sheet" 
                    android:id="@+id/buttonWeddingDayCheatSheet"
                    android:onClick="onClickWeddingDayCheatSheet"
                    android:layout_gravity="center_horizontal">
                </ImageView>
            </FrameLayout>

            <FrameLayout 
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1">
                <ImageView android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:src="@drawable/button_share_favorite_recipe" 
                    android:id="@+id/buttonShareFavoriteRecipe"
                    android:onClick="onClickShareFavoriteRecipe"
                    android:layout_gravity="center_horizontal">
                </ImageView>
                </FrameLayout>
            </TableRow>

    </TableLayout>
person Edmar Miyake    schedule 23.04.2011
comment
Это сработало для меня. Однако мне пришлось добавить center_vertical к элементам FrameLayout. - person Steven; 09.11.2013

Столбцы в таблице Android всегда настраиваются на самый широкий вид в любой строке. Здесь нет явных элементов управления столбцами. Представление сетки имеет больший контроль над размером столбца, например: android:columnWidth="100dp"

Если левое и правое представление в таблице будут иметь одинаковый размер, то центрированная таблица может иметь два столбца с интервалом 50%.

person Lumis    schedule 18.01.2011