GridLayout i Row / Column Span Woe


121

We wpisie na blogu dla deweloperów aplikacji na AndroidaGridLayout przedstawiającym poniższy diagram przedstawiający wpływ rozpiętości na automatyczne przydzielanie indeksów:

automatyczna alokacja indeksu

Próbuję faktycznie zaimplementować to za pomocą GridLayout. Oto, co mam do tej pory:

<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.commonsware.android.gridlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:orientation="horizontal"
    app:columnCount="8">

    <Button
        app:layout_columnSpan="2"
        app:layout_rowSpan="2"
        android:layout_gravity="fill_horizontal"
        android:text="@string/string_1"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_2"/>

  <Button
    app:layout_rowSpan="4"
    android:text="@string/string_3"/>

  <Button
    app:layout_columnSpan="3"
    app:layout_rowSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_4"/>

  <Button
    app:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_5"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_6"/>

  <android.support.v7.widget.Space
    app:layout_column="0"
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

</android.support.v7.widget.GridLayout>

Musiałem wprowadzić <Space>elementy, aby każda kolumna miała minimalną szerokość, w przeciwnym razie miałbym kilka kolumn o zerowej szerokości.

Jednak nawet z nimi dostaję to:

przykładowy układ GridLayout

Szczególnie:

  • Mimo to android:layout_gravity="fill_horizontal"moje widżety z rozpiętościami kolumn nie wypełniają połączonych kolumn

  • Pomimo android:layout_rowSpanwartości nic nie obejmuje rzędów

Czy ktoś może odtworzyć diagram z posta na blogu za pomocą GridLayout?

Dzięki!


178
Myślę, że nawet ty zadajesz pytania :)
StackOverflowed

Odpowiedzi:


76

Wydaje się to dość hakerskie, ale udało mi się uzyskać poprawny wygląd, dodając dodatkową kolumnę i wiersz poza to, co jest potrzebne. Następnie wypełniłem dodatkową kolumnę spacją w każdym wierszu, określając wysokość, a dodatkowy wiersz wypełniłem spacją w każdym kolumnie określającą szerokość. Aby uzyskać dodatkową elastyczność, wyobrażam sobie, że te rozmiary Space można ustawić w kodzie, aby zapewnić coś podobnego do wag. Próbowałem dodać zrzut ekranu, ale nie mam wymaganej reputacji.

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="9"
android:orientation="horizontal"
android:rowCount="8" >

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="1" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="2" />

<Button
    android:layout_gravity="fill_vertical"
    android:layout_rowSpan="4"
    android:text="3" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="4" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="5" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="6" />

<Space
    android:layout_width="36dp"
    android:layout_column="0"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="1"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="2"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="3"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="4"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="5"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="6"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="7"
    android:layout_row="7" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="0" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="1" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="2" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="3" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="4" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="5" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="6" />

</GridLayout>

zrzut ekranu


7
Cóż, IMHO jest stopniowo mniej hakerskie niż inne zaprezentowane do tej pory rozwiązanie - przynajmniej tutaj rozmiary okablowania są w Spaceelementach. Dodałem zrzut ekranu dla przyszłych czytelników. Dzięki!
CommonsWare,

Dlaczego jest rowCountustawiony na 8? Potrzebujemy 4 rzędów (wielkości największego rowSpan) plus jeden dodatkowy, Spacewięc powinno być 5. Czego mi brakuje?
curioustechizen

Po prostu poszedłem z liczbą wierszy i kolumn z obrazka w oryginalnym pytaniu (które samo pochodzi z posta na blogu deweloperów Androida). Następnie dodałem 1 do liczby wierszy i kolumn, aby zrobić miejsce na zewnętrzne obramowanie Spaces. Powinien działać dobrze z zaledwie 5 rzędami.
kturney

5
Uważam, że to rozwiązanie działa tylko <Gridlayout>w przeciwieństwie do<android.support.v7.widget.GridLayout>
Didia

Jak mogę ustawić dynamicznie row_span i rozpiętość kolumn ... to zadziała?

17
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:columnCount="8"
        android:rowCount="7" >

        <TextView
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="2"
            android:background="#a30000"
            android:gravity="center"
            android:text="1"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#0c00a3"
            android:gravity="center"
            android:text="2"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="25dip"
            android:layout_height="100dip"
            android:layout_columnSpan="1"
            android:layout_rowSpan="4"
            android:background="#00a313"
            android:gravity="center"
            android:text="3"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="50dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="2"
            android:background="#a29100"
            android:gravity="center"
            android:text="4"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="25dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="1"
            android:background="#a500ab"
            android:gravity="center"
            android:text="5"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#00a9ab"
            android:gravity="center"
            android:text="6"
            android:textColor="@android:color/white"
            android:textSize="20dip" />
    </GridLayout>

</RelativeLayout>

Zrzut ekranu


2
Dzięki! Co ciekawe, jeśli przejdę na GridLayoutpakiet z pakietu Android Support, układ się psuje, co sugeruje, że nie są one w pełni kompatybilne. Mam też nadzieję, że istnieje sposób, aby to zrobić, który nie wymaga okablowania widżetów. Pozwolę to trochę przetoczyć, aby zobaczyć, jakie inne odpowiedzi przyjdą (jeśli w ogóle), ale zaakceptuję twoje, jeśli nic lepszego się nie pojawi. Dzięki jeszcze raz!
CommonsWare

4
„Jeśli przełączę się na GridLayout z pakietu Android Support, układ się zepsuje” - w rzeczywistości to była moja wina, nie konwertowałem wymaganych android:atrybutów na app:jedynki, używając przestrzeni nazw XML zaplecza. Działa z tylnym portem.
CommonsWare

Znalazłem sposób, aby niektóre z nich miały dynamiczny rozmiar, ale tylko wtedy, gdy pełna szerokość kolumn lub wierszy jest już zdefiniowana przez sąsiednie widoki. Nie sądzę, żeby działały tak jak ciężarki i równomiernie rozprowadzały przestrzeń w zależności od zdefiniowanych rozpiętości. Nie jest idealny, ale działa idealnie w przypadku tego, czego potrzebuję w moim obecnym projekcie.
HandlerExploit

Cóż, twój przykład jest bardziej podobny do podejścia AbsoluteLayout zmieszanego z podejściem do RelativeLayout, prawda? Nie jest to ani dynamiczne, ani przenośne. Dlaczego dokładnie potrzebujesz do tego GridLayout? W każdym razie GridLayout jest, imho, albo uszkodzony, albo niedokończony ...
Bondax

@Bondax Ta implementacja jasno definiuje element siatki zarówno pod względem wysokości, szerokości, szerokości kolumny, jak i rozpiętości kolumn. Układ siatki unosi elementy siatki w ograniczonej przestrzeni, gdy są zdefiniowane różne szerokości siatki (szerokość ekranu). Był to wymóg projektu i to doskonale rozwiązało problem.
HandlerExploit

6

Musisz ustawić w kolumnach zarówno layout_gravity, jak i layout_columntWeight

<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView android:text="سوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="دوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="اول شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />
 </android.support.v7.widget.GridLayout>

2

Biblioteka Android Support V7 GridLayout ułatwia dystrybucję nadmiaru przestrzeni, dostosowując się do zasady wagi. Aby rozciągnąć kolumnę, upewnij się, że komponenty wewnątrz niej definiują wagę lub grawitację. Aby zapobiec rozciąganiu słupa, upewnij się, że jeden z elementów słupa nie definiuje ciężaru ani grawitacji. Pamiętaj o dodaniu zależności dla tej biblioteki. Dodaj com.android.support:gridlayout-v7:25.0.1 w build.gradle.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:rowCount="2">

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="First"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Second"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Third"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"        
    app:layout_columnWeight="1"
    app:layout_rowWeight="1"
    android:text="fourth"/>

</android.support.v7.widget.GridLayout>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.