é possível distribuir botões uniformemente pela largura de um layout linear do Android


247

Eu tenho um layout linear (orientado horizontalmente) que contém 3 botões. Quero que os 3 botões tenham uma largura fixa e sejam distribuídos uniformemente pela largura do layout linear.

Eu posso gerenciar isso definindo a gravidade do layout linear para o centro e depois ajustando o preenchimento dos botões, mas isso funciona para uma largura fixa e não para alterações de dispositivos ou orientações.

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


Respostas:


339

Expandindo resposta das fedj , se você definir layout_widtha 0dpe definir o layout_weightpara cada um dos botões para 1, a largura disponível serão divididos igualmente entre os botões.


81
Para expandir isso, se você não quiser que a largura dos botões seja 1/3 da tela, envolva cada botão em um LinearLayout e defina layout_width = "0dp" e layout_weight = "1" nos 3 LinearLayouts. Além disso, defina a gravidade nos LinearLayouts como "center" para que os botões se alinhem no centro de cada LinearLayout.
— 12133 Andrew

este é o caso para LinearLayout only.can qualquer um dar alguma ideia para equispacing em RelativeLayout
— user1859771

1
No meu caso, eu uso layout_width = "wrap_content" e apenas com layout_weight = "1" funciona bem!
— 27515 StefanM5

Isso não está correto, pois o OP deseja consertar. Veja a resposta de stoefln.
— Mitulát Bati

228

Se você não deseja que os botões sejam redimensionados, mas ajuste o espaçamento entre os botões (espaçamento igual entre todos os botões), você pode usar vistas com peso = "1" que preencherá o espaço entre os botões:

    <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
Esse é definitivamente o método de sobrecarga mais simples e mais baixo que funciona (no caso em que você deseja que o espaço entre as visualizações seja escalado, não as próprias). Estou usando verticalmente e, portanto, apenas troquei os valores de largura e altura. Obrigado.
— Samis

7
Esta é uma solução elegante. Você pode preferir usar o Spacetipo de exibição. Torna as coisas um pouco mais legíveis.
— Ryan R

2
Ryan, sim, se você estiver usando a API 14+ (como deveríamos).
— Eduardo Naveda

Honestamente, eu pensei que não funcionaria quando tivesse 4 botões, mas funcionou brilhantemente sem barulho e medição de tempo de execução. Respeito!
— Ashraf Alshahawy

Isso é melhor do que o aceito atualmente como resposta.
— DroidHeaven

25

Você pode usá-lo da seguinte forma.

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

isso é vassoura !! Eu nunca ouvi falar Spaceaté agora
— Someone Somewhere

21

Você pode fazer isso dando tanto Viewsa layout_widthda 0dpe uma layout_weightde 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>

A maneira como o android layout_weight funciona é:

  • primeiro, ele olha para o tamanho que uma visualização normalmente levaria e reserva esse espaço.
  • segundo, se o layout for match_parent, ele dividirá o espaço restante na proporção de layout_weights. Portanto, se você deu as vistas layout_weight="2"e layout_weight="1", a proporção resultante será de 2 para 1, ou seja: a primeira vista receberá 2/3 do espaço restante e a outra vista 1/3.

É por isso que, se você fornecer layout_widthum tamanho da 0dpprimeira etapa, não terá um significado adicional, já que os dois modos de exibição não receberão nenhum espaço. Então, apenas o segundo ponto decide o espaço que cada um Viewobtém, dando a Views o espaço especificado de acordo com a proporção!

Para explicar por 0dpque o espaço é dividido igualmente, fornecendo um exemplo que mostra o oposto: O código abaixo resultaria em algo diferente, pois example textagora tem uma largura maior do que 0dpporque, ao wrap_contentinvés disso, deixou o espaço livre para dividir menos de 100% porque o texto ocupa espaço. O resultado será que eles obterão 50% do espaço livre restante, mas o texto já TextViewocupará algum espaço, de modo que terá mais de 50% do espaço total.

<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

Bem, se você tiver exatamente 3 botões e se estiver ok (ou até planejado) que os botões externos estejam alinhados aos lados esquerdo e direito, convém tentar um RelativeLayout que seja menos sobrecarga (em muitas situações).

Você pode usar layout_alignParentBottompara alinhar todos os botões com a parte inferior do layout. Use layout_alignParentLeft and Rightpara os botões externos e layout_centerHorizontalpara o botão do meio.

Isso funcionará bem em diferentes orientações e tamanhos de tela.


Para esclarecer, isso não funciona se você tiver mais de três botões.
— Arlomedia

Exatamente. Você precisaria usar um LinearLayout ou RadioGroup (se aplicável).
— Marsbear

11

Você deve dar uma olhada no android: atributo layout_weight


1
Entendi que o atributo layout_weight aumentará o tamanho do botão para preencher o layout. Quero manter o tamanho dos botões constante e apenas aumentar o preenchimento entre os botões.
— yamspog

Ah! Eu realmente não sei a melhor maneira de fazê-lo. Talvez colocando cada botão no layout. O layout 3 com o atributo layout_weight e o botão centralizado no layout. Mas eu realmente não sei se é a melhor maneira de fazê-lo.
— fedj

9

A solução moderna para isso é o 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>

Certifique-se de importar implementation 'com.google.android:flexbox:2.0.0'

Flexboxé muito mais poderoso; é um bom complemento para ConstraintLayout. Este é um ótimo recurso para aprender mais.

Diferença entre space_around, space_between e space_evenly


1
obrigado por me informar. Definitivamente útil. Eu usei "space_around" e os botões estavam bem centralizados quando eu tinha 1 ou 3 visíveis no FlexBox
— Someone Somewhere

4

Para espaçar uniformemente dois botões em um layout linear horizontal, usei 3 objetos LinearLayout para atuar como espaços que serão redimensionados automaticamente. Posicionei esses objetos LinearLayout da seguinte maneira:

[] Botão1 [] Botão2 []

([] representa um objeto LinearLayout usado para espaçamento)

então defino o peso de cada um desses objetos [] LinearLayout como 1 e recebo botões espaçados igualmente.

Espero que isto ajude.



4

Sugiro que você use o atributo weightSum de LinearLayout.

Adicionar a tag android:weightSum="3"à declaração xml do LinearLayout e, em seguida, android:layout_weight="1"aos Buttons resultará na distribuição uniforme dos 3 botões.


4

Isso pode ser conseguido atribuindo weighta cada botão adicionado dentro do contêiner, muito importante para definir a orientação horizontal:

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

para que possamos obter isso em nosso dispositivo como resultado:

insira a descrição da imagem aqui

mesmo que rotacionemos nosso dispositivo, o weightdefinido em cada botão pode distribuir os elementos uniformemente ao longo do contêiner:

insira a descrição da imagem aqui


3

A melhor abordagem é usar TableLayout com android: layout_width = "match_parent" e nas colunas usar android: layout_weight = "1" para todas as colunas


2

As respostas acima usando layout_d não funcionaram para mim, mas o seguinte funcionou.

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

É assim que fica na tela,

insira a descrição da imagem aqui


2

Acima de todas as respostas, as respostas estão corretas, mas, em um caso, você precisa de recursos visíveis e passados, esse método pragmaticamente funcionará bem

<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

Crianças com o mesmo peso

Para criar um layout linear no qual cada filho use a mesma quantidade de espaço na tela, defina o android: layout_height de cada visualização como "0dp" (para um layout vertical) ou o android: layout_width de cada visualização para "0dp" ( para um layout horizontal). Em seguida, defina o android: layout_weight de cada visualização como "1".

Para que isso funcione no LinearLayoutgrupo de vistas, os valores dos atributos android:layout_widthe android:layout_heightprecisam ser iguais a "match_parent"...


Graças uma tonelada companheiro! Economizou muito tempo.
— Xonshiz 26/04

1
Sem problemas, companheiro.
— Gibran Castillo

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>

Em círculo, Tom, Tim e Todd assumem 3 centímetros. Se você quiser que seja uma tela de toque, coloque-o como Tom e Tim assumindo 1 centímetro, o que significa que eles combinam virtual, mas seu plano 2D está na parte inferior. Isso é exibido na tela.


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

A maneira mais fácil e rápida (mas não a melhor) é adicionar um TextView com atributo de texto vazio, como este

android:text=""

a cor do plano de fundo deve ser a mesma no LinearLayout, você pode usar a propriedade padding, como esta

android:paddingBottom="250dp"

ou o que você precisar. Aqui está um exemplo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.