¿Es posible distribuir uniformemente los botones en todo el ancho de una distribución lineal de Android?


247

Tengo un diseño lineal (orientado horizontalmente) que contiene 3 botones. Quiero que los 3 botones tengan un ancho fijo y se distribuyan uniformemente en todo el ancho del diseño lineal.

Puedo manejar esto configurando la gravedad de la distribución lineal en el centro y luego ajustando el relleno de los botones, pero esto funciona para un ancho fijo y no funcionará para cambiar dispositivos u orientaciones.

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


Respuestas:


339

Ampliando la respuesta de Fedj , si se establece layout_widtha 0dpy se establece el layout_weightde cada uno de los botones a 1, la anchura disponible se repartirá a partes iguales entre los botones.


81
Para ampliar esto, si no desea que el ancho de los botones sea 1/3 de la pantalla, ajuste cada botón en LinearLayout y configure layout_width = "0dp" y layout_weight = "1" en los 3 LinearLayouts. Además, establezca la gravedad en LinearLayouts en "centro" para que los botones se alineen en el centro de cada LinearLayout.
Andrew

este es el caso solo para linearlayout. cualquiera puede dar una idea para equispacing en relativolayout
user1859771

1
En mi caso, uso layout_width = "wrap_content" y solo con layout_weight = "1" funciona bien.
StefanoM5

Esto no es correcto, ya que el OP quiere arreglarlo. Ver la respuesta de stoefln.
Mitulát báti

228

Si no desea que los botones se escalen, pero ajuste el espacio entre los botones (espacio igual entre todos los botones), puede usar vistas con peso = "1" que llenará el espacio entre los botones:

    <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
Este es definitivamente el método de sobrecarga más simple y más bajo que funciona (para el caso en que desea que el espacio entre las vistas se escale, no las vistas en sí). Lo estoy usando verticalmente, por lo que simplemente cambié los valores de ancho y alto. Gracias.
samis

77
Esta es una solución elegante. Es posible que prefiera usar el Spacetipo de vista. Hace las cosas un poco más legibles.
Ryan R

2
Ryan, sí, eso es si estás utilizando API 14+ (como deberíamos).
Eduardo Naveda

Honestamente, pensé que no funcionaría cuando tenía 4 botones, pero funcionó de manera brillante sin complicaciones y medidas de tiempo de ejecución. ¡El respeto!
Ashraf Alshahawy

Esto es mejor que el que se acepta como respuesta actualmente.
DroidHeaven

25

Puede usarlo con lo siguiente.

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

eso es dulce !! Nunca escuché hablar Spacehasta ahora
alguien en algún lugar el

21

Puede hacer esto dando tanto Viewsa layout_widthde 0dpcomo a 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>

La forma en que funciona android layout_weight es que:

  • primero, se ve al tamaño que normalmente tomaría una vista y reserva este espacio.
  • segundo, si el diseño es match_parententonces, dividirá el espacio que queda en la proporción de layout_weights. Por lo tanto, si proporcionó las Vistas layout_weight="2"y layout_weight="1", la relación resultante será de 2 a 1, es decir: la primera Vista obtendrá 2/3 del espacio que queda y la otra vista 1/3.

Es por eso que si le das layout_widthun tamaño 0dpal primer paso no tiene ningún significado agregado ya que a ambas Vistas no se les asigna ningún espacio. ¡Entonces solo el segundo punto decide el espacio que cada uno Viewtiene, dando así a Views el espacio que especificó de acuerdo con la proporción!

Para explicar por qué 0dpel espacio se divide igualmente al proporcionar un ejemplo que muestra lo contrario: el código a continuación daría como resultado algo diferente, ya que example textahora tiene un ancho que es mayor que 0dpporque, en wrap_contentcambio, deja que el espacio libre se divida menos del 100% porque el texto ocupa espacio El resultado será que tendrán el 50% del espacio libre restante, pero el texto ya tomó algo de espacio, por lo TextViewque tendrá más del 50% del espacio 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

Bueno, si tiene exactamente 3 botones y está bien (o incluso planeado) que los botones externos estén alineados con el lado izquierdo y derecho, entonces puede probar un RelativeLayout que tenga menos gastos generales (en muchas situaciones).

Puede usar layout_alignParentBottompara alinear todos los botones con la parte inferior del diseño. Úselo layout_alignParentLeft and Rightpara los botones exteriores y layout_centerHorizontalpara el botón central.

Eso funcionará bien en diferentes orientaciones y tamaños de pantalla.


Para aclarar, esto no funciona si tiene más de tres botones.
arlomedia

Exactamente. Tendría que usar un LinearLayout o RadioGroup (si corresponde) en su lugar.
marsbear

11

Deberías echar un vistazo a android: atributo layout_weight


1
Entendí que el atributo layout_weight estirará el tamaño del botón para llenar el diseño. Quiero mantener constante el tamaño de los botones y solo aumentar el relleno entre los botones.
yamspog

Ah! Realmente no sé la mejor manera de hacerlo. Quizás encerrando cada botón en el diseño. El diseño 3 con el atributo layout_weight y el botón centrado en el diseño. Pero realmente no sé si es la mejor manera de hacerlo.
fedj

9

La solución moderna para esto es 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>

Asegúrate de importar implementation 'com.google.android:flexbox:2.0.0'

Flexboxes mucho más poderoso Es un buen complemento para ConstraintLayout. Este es un gran recurso para aprender más.

Diferencia entre space_around, space_between y space_evenly


1
gracias por hacerme (nosotros) consciente de ello. Definitivamente útil. Usé "space_around" y los botones estaban bien centrados cuando tenía 1 o 3 visibles dentro del FlexBox
Alguien en algún lugar

4

Para espaciar uniformemente dos botones en un diseño lineal horizontal, utilicé 3 objetos LinearLayout para actuar como espacios que se redimensionarán automáticamente. Coloqué estos objetos LinearLayout de la siguiente manera:

[] Botón1 [] Botón2 []

([] representa un objeto LinearLayout utilizado para el espaciado)

luego establezco los pesos de cada uno de estos objetos [] LinearLayout en 1, y obtengo botones espaciados uniformemente.

Espero que esto ayude.



4

Le sugiero que use el atributo weightSum de LinearLayout.

Agregar la etiqueta android:weightSum="3"a la declaración xml de LinearLayout y luego android:layout_weight="1"a los botones dará como resultado que los 3 botones se distribuyan de manera uniforme.


4

Esto se puede lograr asignando weighta cada botón agregado dentro del contenedor, muy importante para definir la orientación 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 podamos obtener esto en nuestro dispositivo como resultado:

ingrese la descripción de la imagen aquí

incluso si giramos nuestro dispositivo, lo weightdefinido en cada botón puede distribuir los elementos uniformemente a lo largo del contenedor:

ingrese la descripción de la imagen aquí


3

El mejor enfoque es usar TableLayout con android: layout_width = "match_parent" y en columnas usar android: layout_weight = "1" para todas las columnas


2

Las respuestas anteriores usando layout_no me funcionaron, pero lo siguiente sí.

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

Así es como se ve en la pantalla,

ingrese la descripción de la imagen aquí


2

Sobre todo, las respuestas son correctas, pero en el caso de que necesite características visibles y desaparecidas, este método pragmático funcionará bien

<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

Niños con igual peso

Para crear un diseño lineal en el que cada niño use la misma cantidad de espacio en la pantalla, configure android: layout_height de cada vista en "0dp" (para un diseño vertical) o android: layout_width de cada vista en "0dp" ( para un diseño horizontal). Luego configure el android: layout_weight de cada vista en "1".

Para que esto funcione en el LinearLayoutgrupo de vista, los valores de atributo android:layout_widthy android:layout_heightdeben ser iguales a "match_parent"...


Muchas gracias amigo! Ahorro de mucho tiempo.
Xonshiz

1
No hay problema amigo.
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>

En círculo, se supone que Tom, Tim y Todd miden 3 centímetros. Si desea que sea una pantalla táctil, póngalo como Tom y Tim suponiendo que es 1 centímetro, lo que significa que combinan virtual pero su plano 2D está en la parte inferior. Esto se muestra en la pantalla.


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

La forma más fácil y rápida (pero no la mejor) es agregar un TextView con un atributo de texto vacío, como este

android:text=""

el color de fondo debe ser el mismo en LinearLayout, entonces puede usar la propiedad de relleno, como esta

android:paddingBottom="250dp"

o lo que necesites. Aquí hay un ejemplo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.