czy możliwe jest równomierne rozmieszczenie przycisków na całej szerokości liniowego systemu Android?

247

Mam układ liniowy (zorientowany poziomo), który zawiera 3 przyciski. Chcę, aby 3 przyciski miały stałą szerokość i były równomiernie rozmieszczone na szerokości układu liniowego.

Mogę sobie z tym poradzić, ustawiając grawitację liniowego podziału na środek, a następnie dostosowując dopełnienie przycisków, ale działa to na ustaloną szerokość i nie będzie działać przy zmianie urządzeń lub orientacji.

<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>
jamspog
źródło

Odpowiedzi:

339

Rozwijając na odpowiedź fedj męska , jeśli ustawisz layout_widthsię 0dpi ustawić layout_weightdla każdego z przycisków 1, dostępna szerokość zostanie podzielona równo pomiędzy przyciskami.

Dan Dyer
źródło
81
Aby rozwinąć tę kwestię, jeśli nie chcesz, aby szerokość przycisków wynosiła 1/3 ekranu, zawiń każdy przycisk w LinearLayout i ustaw layout_width = "0dp" i layout_weight = "1" na 3 LinearLayouts. Dodatkowo ustaw grawitację na LinearLayouts na „środek”, aby przyciski wyrównały się na środku każdego LinearLayout.
Andrew,
dotyczy to tylko liniowej rozgrywki. czy ktoś może dać jakiś pomysł na wyrównanie w
układzie
1
W moim przypadku używam layout_width = "wrap_content" i tylko z layout_weight = "1" działa dobrze!
StefanoM5
To nie jest poprawne, ponieważ OP chce to naprawić. Zobacz odpowiedź stoefln.
Mitulát báti
228

Jeśli nie chcesz, aby przyciski były skalowane, ale dostosuj odstępy między przyciskami (równe odstępy między wszystkimi przyciskami), możesz użyć widoków o wadze = „1”, które wypełnią przestrzeń między przyciskami:

    <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>
stoefln
źródło
15
Jest to zdecydowanie najprostsza, najniższa metoda narzutu, która działa (w przypadku, gdy chcesz, aby przestrzeń między widokami była skalowana, a nie same widoki). Używam go pionowo, więc po prostu zamieniłem wartości szerokości i wysokości. Dzięki.
samis,
7
To eleganckie rozwiązanie. Może wolisz użyć Spacetypu widoku. Sprawia, że ​​rzeczy są nieco bardziej czytelne.
Ryan R
2
Ryan, tak, to znaczy, jeśli używasz API 14+ (tak jak powinniśmy).
Eduardo Naveda,
Szczerze mówiąc, myślałem, że to nie zadziała, mając 4 przyciski, ale działało doskonale, bez problemów i pomiaru czasu pracy. Szacunek!
Ashraf Alshahawy,
To jest lepsze niż to, które jest obecnie akceptowane jako odpowiedź.
DroidHeaven
25

Możesz używać go w następujący sposób.

<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>
Sandhu
źródło
to słodycz !! SpaceDo tej pory nie słyszałem
Ktoś gdzieś
21

Można to zrobić poprzez nadanie zarówno ViewSA layout_widthz 0dporaz layout_weightz 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>

Sposób działania android layout_weight polega na tym, że:

  • po pierwsze, wygląda na rozmiar, który normalnie przyjmuje Widok i rezerwuje to miejsce.
  • po drugie, jeśli układ jest, match_parentto podzieli przestrzeń, która pozostała w stosunku layout_weights. Tak więc, jeśli dał widoków layout_weight="2"i layout_weight="1"stosunek wypadkowa będzie 2 do 1, czyli: pierwsza Zobacz dostanie 2/3 przestrzeni, która jest po lewej, a drugi widzenia 1/3.

Dlatego właśnie, jeśli podasz layout_widthrozmiar 0dppierwszego kroku, nie ma żadnego dodatkowego znaczenia, ponieważ do obu widoków nie przypisano żadnej spacji. Wtedy tylko drugi punkt decyduje o tym, jaką przestrzeń Viewotrzymuje każdy , dając w ten sposób Views określoną przez ciebie przestrzeń zgodnie ze współczynnikiem!

Aby wyjaśnić, dlaczego 0dppowoduje równe dzielenie się przestrzeni, podając przykład, który pokazuje coś przeciwnego: poniższy kod spowodowałby coś innego, ponieważ example textteraz ma szerokość większą niż 0dpdlatego, że wrap_contentzamiast tego pozostawia wolne miejsce do podzielenia mniej niż 100% ponieważ tekst zajmuje miejsce. W rezultacie otrzymają 50% wolnego miejsca, ale tekst już zajął trochę miejsca, więc TextViewbędzie miał znacznie ponad 50% całkowitej przestrzeni.

<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>
Joop
źródło
13

Cóż, jeśli masz dokładnie 3 przyciski i jeśli ok (lub nawet planujesz), że zewnętrzne przyciski są wyrównane do lewej i prawej strony, możesz spróbować zastosować RelativeLayout, który jest mniej obciążony (w wielu sytuacjach).

Możesz użyć, layout_alignParentBottomaby wyrównać wszystkie przyciski z dolną częścią układu. Użyj layout_alignParentLeft and Rightdla zewnętrznych przycisków i layout_centerHorizontaldla środkowego przycisku.

Działa to dobrze w różnych orientacjach i rozmiarach ekranu.

marsbear
źródło
Aby to wyjaśnić, nie działa to, jeśli masz więcej niż trzy przyciski.
arlomedia,
Dokładnie. Zamiast tego musisz użyć LinearLayout lub RadioGroup (jeśli dotyczy).
marsbear
11

Powinieneś spojrzeć na atrybut android: layout_weight

fedj
źródło
1
Rozumiałem, że atrybut layout_weight spowoduje rozciągnięcie rozmiaru przycisku w celu wypełnienia układu. Chcę zachować stały rozmiar przycisków i po prostu zwiększyć wypełnienie między przyciskami.
yamspog,
Ach! Naprawdę nie znam najlepszego sposobu, aby to zrobić. Być może zamknięcie każdego przycisku w układzie. 3 układ z atrybutem layout_weight i przycisk wyśrodkowany w układzie. Ale tak naprawdę nie wiem, czy to najlepszy sposób, aby to zrobić.
fedj
9

Nowoczesnym rozwiązaniem tego jest 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>

Pamiętaj, aby zaimportować implementation 'com.google.android:flexbox:2.0.0'

Flexboxjest znacznie potężniejszy; jest dobrym uzupełnieniemConstraintLayout . To świetny zasób, aby dowiedzieć się więcej.

Różnica między spacją, spacją między i spacją

Gibolt
źródło
1
dzięki za poinformowanie mnie (nas) o tym. Zdecydowanie przydatne. Użyłem „space_around”, a przyciski były ładnie wyśrodkowane, gdy miałem 1 lub 3 widoczne w FlexBox
ktoś gdzieś
4

Aby równomiernie rozmieścić dwa przyciski w poziomym układzie liniowym, użyłem 3 obiektów LinearLayout, które działają jak przestrzenie, których rozmiar zostanie automatycznie zmieniony. Ustawiłem te obiekty LinearLayout w następujący sposób:

[] Przycisk 1 [] Przycisk 2 []

([] reprezentuje obiekt LinearLayout używany do odstępów)

następnie ustawiam wagi każdego z tych [] obiektów LinearLayout na 1 i otrzymuję równomiernie rozmieszczone przyciski.

Mam nadzieję że to pomoże.

Mahomet
źródło
4

Sugeruję użycie atrybutu weightSum LinearLayout.

Dodanie znacznika android:weightSum="3"do deklaracji xml LinearLayout, a następnie android:layout_weight="1"do przycisków spowoduje równomierne rozmieszczenie 3 przycisków.

matdev
źródło
4

Można to osiągnąć, przypisując weightdo każdego przycisku dodanego w pojemniku, bardzo ważne, aby zdefiniować orientację poziomą:

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

dzięki czemu możemy uzyskać to w naszym urządzeniu:

wprowadź opis zdjęcia tutaj

nawet jeśli weightobrócimy nasze urządzenie, zdefiniowane w każdym przycisku mogą równomiernie rozdzielić elementy wzdłuż pojemnika:

wprowadź opis zdjęcia tutaj

Jorgesys
źródło
3

Najlepszym rozwiązaniem jest użycie TableLayout z systemem Android: layout_width = "match_parent", aw kolumnach użycie Androida: layout_weight = "1" dla wszystkich kolumn

Prashant
źródło
2

Powyższe odpowiedzi przy użyciu układu nie działały dla mnie, ale następujące zadziałały.

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

Tak to wygląda na ekranie,

wprowadź opis zdjęcia tutaj

Sean Le Roy
źródło
2

Przede wszystkim odpowiedzi są poprawne, ale w przypadku, gdy potrzebujesz widocznych i nieistniejących funkcji, ta pragmatycznie metoda będzie działać dobrze

<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;
    }
}
Rajesh Nasit
źródło
2

Dzieci o równej wadze

Aby utworzyć układ liniowy, w którym każde dziecko wykorzystuje tę samą ilość miejsca na ekranie, ustaw android: layout_height każdego widoku na „0dp” (dla układu pionowego) lub android: layout_width każdego widoku na „0dp” ( dla układu poziomego). Następnie ustaw android: layout_weight każdego widoku na „1”.

Aby działało to w LinearLayoutgrupie widoków, wartości atrybutów android:layout_widthi android:layout_heightmuszą być równe "match_parent"...

Gibran Castillo
źródło
Dzięki kolego z tony! Zaoszczędziłem dużo czasu.
Xonshiz
1
Nie ma problemu kolego.
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>

W kole zakłada się, że Tom, Tim i Todd mają 3 centymetry. Jeśli chcesz, aby ekran dotykowy był w dół, ustaw go, gdy Tom i Tim przyjmą, że ma 1 centymetr, co oznacza, że ​​łączą się wirtualnie, ale jego płaszczyzna 2D znajduje się na dole. Jest to wyświetlane na ekranie.

Dinesh Gowd
źródło
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" />

basem
źródło
0

Najłatwiejszym i najszybszym (ale nie najlepszym) sposobem jest dodanie TextView z pustym atrybutem tekstowym, jak to

android:text=""

kolor tła musi być taki sam na LinearLayout, wtedy możesz użyć właściwości padding, jak to

android:paddingBottom="250dp"

lub cokolwiek potrzebujesz. Oto przykład.

Cesar Bobadilla
źródło