Можно ли равномерно распределить кнопки по ширине линейного макета Android?


247

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

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

<LinearLayout android:id="@+id/LinearLayout01" 
android:layout_height="wrap_content" 
android:orientation="horizontal" 
android:layout_width="fill_parent" 
android:gravity="center">

<Button 
android:id="@+id/btnOne"
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:width="120dip"></Button>

<Button 
android:id="@+id/btnTwo"
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:width="120dip"></Button>


<Button 
android:id="@+id/btnThree"
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:width="120dip"></Button>

</LinearLayout>

Дублирование? stackoverflow.com/questions/3450561/...

Ответы:


339

Развивая ответ fedj игрового , если вы установите layout_widthна 0dpи установить layout_weightдля каждого из кнопок 1, имеющаяся ширина будет разделена поровну между кнопками.


81
Чтобы расширить это, если вы не хотите, чтобы ширина кнопок составляла 1/3 экрана, оберните каждую кнопку в LinearLayout и установите layout_width = "0dp" и layout_weight = "1" на 3 LinearLayouts. Кроме того, установите гравитацию на LinearLayouts на «center», чтобы кнопки были выровнены по центру каждого LinearLayout.
Андрей

это относится только к linearlayout. Может ли кто-нибудь дать представление о равномерном распределении относительных
размеров

1
В моем случае я использую layout_width = "wrap_content" и только с layout_weight = "1" работает хорошо!
StefanoM5

Это не правильно, так как OP хочет исправить с помощью. Смотри ответ Stoefln.
Mitulát báti

228

Если вы не хотите, чтобы кнопки масштабировались, а отрегулировали расстояние между кнопками (равное расстояние между всеми кнопками), вы можете использовать представления с weight = "1", которые заполнят пространство между кнопками:

    <Space
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:layout_weight="1" >
    </Space>

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:background="@null"
        android:gravity="center_horizontal|center_vertical"
        android:src="@drawable/tars_active" />

    <Space
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:layout_weight="1" >
    </Space>

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:background="@null"
        android:gravity="center_horizontal|center_vertical"
        android:src="@drawable/videos_active" />

    <Space
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:layout_weight="1" >
    </Space>

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

7
Это элегантное решение. Вы можете предпочесть использовать Spaceтип представления. Делает вещи немного более читабельными.
Райан Р

2
Райан, да, это если вы используете API 14+ (как мы и должны).
Эдуардо Наведа

Честно говоря, я думал, что это не будет работать при наличии 4 кнопок, но он работал блестяще, без суеты и измерения времени выполнения. Респект!
Ашраф Альшахави

Это лучше, чем тот, который принят в качестве ответа в настоящее время.
DroidHeaven

25

Вы можете использовать его как ниже.

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_marginTop="15dp">
    <Space
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save"/>
    <Space
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Reset"/>
    <Space
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="cancel"/>
    <Space
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
</LinearLayout>

это сладко !! Я никогда не слышал Spaceдо сих пор
кто-то где-то

21

Вы можете сделать это, указав Viewsa layout_widthof 0dpи a layout_weightof 1:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <TextView
        android:layout_width="0dp"
        android:text="example text"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

</LinearLayout>

Работает android layout_weight так:

  • во-первых, он смотрит на размер, который обычно принимает View, и резервирует это пространство.
  • во-вторых, если это макет, match_parentто он разделит оставшееся пространство в соотношении layout_weights. Таким образом, если вы задали Views layout_weight="2"и layout_weight="1", результирующее соотношение будет 2: 1, то есть: первый View получит 2/3 от оставшегося пространства, а другой - 1/3.

Вот почему, если вы укажете layout_widthразмер 0dpпервого шага, не будет иметь никакого дополнительного значения, так как обоим представлениям не назначено никакого пространства. Тогда только вторая точка решает, сколько места Viewполучит каждый , давая тем Viewсамым пространство, которое вы указали в соответствии с соотношением!

Чтобы объяснить причину, 0dpпо которой пространство делится поровну, приведем пример, демонстрирующий обратное: приведенный ниже код приведет к чему-то другому, поскольку example textтеперь его ширина больше, чем 0dpпотому, что wrap_contentвместо этого свободное пространство остается делить менее 100%. потому что текст занимает место. В результате они получают 50% свободного места, но текст уже занял некоторое пространство, поэтому у него TextViewбудет более 50% общего пространства.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <TextView
        android:layout_width="wrap_content"
        android:text="example text"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

</LinearLayout>

13

Что ж, если у вас ровно 3 кнопки, и если все в порядке (или даже запланировано), что внешние кнопки выровнены по левому и правому краю, то вы можете попробовать RelativeLayout, который требует меньше накладных расходов (во многих ситуациях).

Вы можете использовать layout_alignParentBottomдля выравнивания всех кнопок с нижней части макета. Используйте layout_alignParentLeft and Rightдля внешних кнопок и layout_centerHorizontalдля средней кнопки.

Это будет хорошо работать на разных ориентациях и размерах экрана.


Чтобы уточнить, это не работает, если у вас более трех кнопок.
arlomedia

Именно. Вместо этого вам придется использовать LinearLayout или RadioGroup (если применимо).
marsbear

11

Вы должны взглянуть на Android: layout_weight атрибут


1
Насколько я понимаю, атрибут layout_weight будет растягивать размер кнопки, чтобы заполнить макет. Я хочу сохранить размер кнопок постоянным и просто увеличить отступ между кнопками.
yamspog

Ах! Я действительно не знаю лучший способ сделать это. Возможно, вложение каждой кнопки в макете. 3 макета с атрибутом layout_weight и кнопкой по центру макета. Но я действительно не знаю, является ли это лучшим способом сделать это.
Федж

9

Современное решение для этого - Flexbox .

<com.google.android.flexbox.FlexboxLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:justifyContent="space_around"> <!-- or "space_between", "space_evenly" -->

    <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:width="120dp" />

    <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:width="120dp" />

    <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:width="120dp" />
</com.google.android.flexbox.FlexboxLayout>

Не забудьте импортировать implementation 'com.google.android:flexbox:2.0.0'

Flexboxгораздо мощнее; это хорошее дополнение к ConstraintLayout. Это отличный ресурс, чтобы узнать больше.

Разница между space_around, space_between и space_evenly


1
спасибо, что заставили меня (нас) осознать это. Определенно полезно. Я использовал «space_around», и кнопки были хорошо отцентрированы, когда я увидел 1 или 3 в FlexBox
кто-то где-то

4

Для равномерного распределения двух кнопок в горизонтальной линейной компоновке я использовал 3 объекта LinearLayout, которые будут действовать как пространства, размер которых будет автоматически изменяться. Я разместил эти объекты LinearLayout следующим образом:

[] Button1 [] Button2 []

([] представляет объект LinearLayout, используемый для разнесения)

затем я устанавливаю вес каждого из этих объектов [] LinearLayout равным 1, и я получаю равномерно расположенные кнопки.

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



4

Я предлагаю вам использовать атрибут weightSum LinearLayout.

Добавление тега android:weightSum="3"в xml-декларацию LinearLayout, а затем android:layout_weight="1"в кнопки - приведет к равномерному распределению трех кнопок.


4

Это может быть достигнуто назначением weightкаждой кнопки, добавленной внутри контейнера, очень важно определить горизонтальную ориентацию:

    int buttons = 5;

    RadioGroup rgp = (RadioGroup) findViewById(R.id.radio_group);

    rgp.setOrientation(LinearLayout.HORIZONTAL);

    for (int i = 1; i <= buttons; i++) {
        RadioButton rbn = new RadioButton(this);         
        rbn.setId(1 + 1000);
        rbn.setText("RadioButton" + i);
        //Adding weight
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1f);
        rbn.setLayoutParams(params);
        rgp.addView(rbn);
    }

поэтому мы можем получить это в нашем устройстве в результате:

введите описание изображения здесь

даже если мы вращаем наше устройство, weightопределенные в каждой кнопке элементы могут равномерно распределяться по контейнеру:

введите описание изображения здесь


3

Лучший подход - использовать TableLayout с android: layout_width = "match_parent", а в столбцах использовать android: layout_weight = "1" для всех столбцов


2

Приведенные выше ответы с использованием layout_ не сработали для меня, но следующие сработали.

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_weight="0.1"
    android:layout_gravity="center_horizontal"
    >

    <android.support.design.widget.FloatingActionButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
       />

    <android.support.design.widget.FloatingActionButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginStart="40dp"/>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginStart="40dp"
        />

    <android.support.design.widget.FloatingActionButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginStart="40dp"/>

</LinearLayout>

Вот как это выглядит на экране,

введите описание изображения здесь


2

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

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnOne"
            android:layout_width="120dp"
            android:layout_height="match_parent"></Button>

        <Button
            android:id="@+id/btnTwo"
            android:layout_width="120dp"
            android:layout_height="match_parent"></Button>


        <Button
            android:id="@+id/btnThree"
            android:layout_width="120dp"
            android:layout_height="match_parent"></Button>
    </LinearLayout>



 float width=CommonUtills.getScreenWidth(activity);
            int cardWidth=(int)CommonUtills.convertDpToPixel (((width)/3),activity);

LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(width,
                        LinearLayout.LayoutParams.MATCH_PARENT);

btnOne.setLayoutParams(params);
btnTwo.setLayoutParams(params);
btnThree.setLayoutParams(params);

public class CommonUtills {
public static float getScreenWidth(Context context) {
        float width = (float) 360.0;
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        width = displayMetrics.widthPixels / displayMetrics.density;
        return width;
    }
}

2

Равно взвешенные дети

Чтобы создать линейный макет, в котором каждый дочерний элемент использует одинаковое количество места на экране, установите для android: layout_height каждого вида значение «0dp» (для вертикального макета) или для android: layout_width каждого вида значение «0dp» ( для горизонтального расположения). Затем установите для android: layout_weight каждого вида значение «1».

Чтобы это работало в LinearLayoutгруппе представлений, значения атрибутов для android:layout_widthи android:layout_heightдолжны быть равны "match_parent"...


Спасибо, приятель! Сэкономил много времени.
Ксоншиз

1
Нет проблем, приятель.
Гибран Кастильо

0
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="Tom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="24sp" 
        android:layout_weight="3"/>

    <TextView
        android:text="Tim"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="24sp"
        android:layout_weight="3"/>

    <TextView
        android:text="Todd"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="24sp" 
        android:layout_weight="3"/>

</LinearLayout>

В кругу Том, Тим и Тодд получают 3 сантиметра. Если вы хотите, чтобы это был сенсорный экран, укажите, что у Тома и Тима предполагается, что они равны 1 сантиметру, что означает, что они объединяют виртуальный, но его 2D плоскость находится внизу. Это отображается на экране.


0
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<TextView
    android:text="Tom"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:textSize="24sp" />

<TextView
    android:text="Tim"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:textSize="24sp" />

<TextView
    android:text="Todd"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:textSize="24sp" />


0

Самый простой и быстрый способ (но не самый лучший) - добавить TextView с пустым текстовым атрибутом, например так:

android:text=""

цвет фона должен быть одинаковым в LinearLayout, тогда вы можете использовать свойство padding, как это

android:paddingBottom="250dp"

или что вам нужно. Вот пример.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.