Układy w widokach
Układ określa strukturę interfejsu użytkownika aplikacji, np.
aktywność. Wszystkie elementy w
układ jest oparty na hierarchii
View
i
ViewGroup
obiektów. View
zwykle rysuje coś, co użytkownik widzi
wchodzą w interakcję z reklamą. ViewGroup
to niewidoczny kontener, który określa
struktura układu dla View
i innych elementów ViewGroup
jak na ilustracji 1.
Obiekty View
są często nazywane widżetami i mogą być jednym z
wiele podklas, takich jak
Button
lub
TextView
.
Obiekty ViewGroup
są zwykle nazywane układami i mogą być jednym z nich
różne typy o różnej strukturze układu, np.
LinearLayout
lub
ConstraintLayout
Układ możesz zadeklarować na 2 sposoby:
- Deklarowanie elementów interfejsu w pliku XML. Android zapewnia prosty kod XML
słownik, który odpowiada klasom i podklasom (
View
), np. widżetów i układów. Możesz też użyć narzędzia Android Studio, Edytor układów do tworzenia kodu XML. układ za pomocą interfejsu typu „przeciągnij i upuść”. - Twórz instancje elementów układu w czasie działania. Aplikacja może tworzyć
View
iViewGroup
obiektów i manipuluj nimi w sposób zautomatyzowany.
Zadeklarowanie interfejsu w formacie XML pozwala oddzielić sposób prezentacji aplikacji od który kontroluje jego działanie. Użycie plików XML ułatwia też udostępnić różne układy do różnych rozmiarów i orientacji ekranu. To jest omówiono szerzej tutaj: Obsługuj różne ekrany .
Platforma Androida zapewnia elastyczność – możesz korzystać z jednego lub obu do tworzenia interfejsu aplikacji. Możesz na przykład zadeklarować, domyślnych układach w pliku XML, a następnie modyfikować je w czasie działania.
Zapisz kod XML
Korzystając ze słownika XML na Androida, możesz szybko projektować układy interfejsu zawarte w nich elementy ekranu, tak samo jak w przypadku tworzenia stron internetowych w języku HTML z serią zagnieżdżonych elementów.
Każdy plik układu musi zawierać dokładnie jeden element główny, który musi być tagiem
Obiekt View
lub ViewGroup
. Po zdefiniowaniu poziomu głównego
, możesz dodać do niego dodatkowe obiekty układu lub widżety jako elementy podrzędne
stopniowo twórz hierarchię View
, która definiuje układ. Dla:
Oto układ XML, w którym pionowa wartość LinearLayout
pozwala
zawierają TextView
i Button
:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>
Po zadeklarowaniu układu w pliku XML zapisz plik z atrybutem
.xml
rozszerzenie w projekcie res/layout/
w projekcie na Androida
w celu poprawnej kompilacji.
Więcej informacji na temat składni pliku XML układu znajdziesz tutaj Zasób układu.
Wczytaj zasób XML
Podczas kompilowania aplikacji każdy plik układu XML jest kompilowany w
View
zasób. Wczytaj zasób szablonu do pliku
Activity.onCreate()
implementacji wywołania zwrotnego. Aby to zrobić, zadzwoń pod numer
setContentView()
,
przekazując je do zasobu układu w formularzu:
R.layout.layout_file_name
Na przykład, jeśli plik XML
układ został zapisany jako main_layout.xml
, wczytaj go na swoim
Activity
w następujący sposób:
Kotlin
fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.main_layout) }
Java
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }
Platforma Androida wywołuje metodę wywołania zwrotnego onCreate()
w
Activity
po uruchomieniu Activity
. Więcej
informacje o cyklach życia działań, zobacz
Wprowadzenie do
aktywności.
Atrybuty
Każdy obiekt View
i ViewGroup
obsługuje własne
różne atrybuty XML. Niektóre atrybuty są charakterystyczne dla atrybutu View
obiektu. Na przykład TextView
obsługuje textSize
. Te atrybuty są jednak również dziedziczone przez dowolne View
które rozszerzają tę klasę. Niektóre są wspólne dla wszystkich: View
ponieważ są one dziedziczone z klasy głównej View
, takiej jak
atrybut id
. Inne atrybuty są uznawane za układ
parametrów, które opisują określone orientacje układu.
obiektu View
zdefiniowanego przez jego obiekt nadrzędny
ViewGroup
obiekt.
ID
Z dowolnym obiektem View
może być powiązany identyfikator całkowity w celu
jednoznacznie identyfikują View
w drzewie. Gdy aplikacja jest
jest skompilowany, identyfikator ten jest przywoływany w postaci liczby całkowitej, ale identyfikator jest zwykle przypisywany
w pliku XML układu jako ciąg znaków w atrybucie id
. To jest
Atrybut XML wspólny dla wszystkich obiektów View
, który jest definiowany przez klucz
View
zajęcia. Bardzo często go używasz. Składnia identyfikatora wewnątrz tagu
Tag XML wygląda tak:
android:id="@+id/my_button"
Symbol at (@) na początku ciągu oznacza, że:
Parser XML analizuje i rozwija resztę ciągu znaków identyfikatora, identyfikując go jako
zasobu identyfikatora. Symbol plusa (+) oznacza, że jest to nowa nazwa zasobu.
które należy utworzyć i dodać do zasobów w R.java
.
Platforma Androida udostępnia też wiele innych zasobów związanych z identyfikatorem. Gdy odwołujesz się do
identyfikatora zasobu Androida, nie potrzebujesz symbolu plusa, ale musisz dodać
Przestrzeń nazw pakietu android
w ten sposób:
android:id="@android:id/empty"
Przestrzeń nazw pakietu android
wskazuje, że odwołujesz się
identyfikator z klasy zasobów android.R
, a nie lokalnego
w ramach klasy zasobów.
Aby tworzyć widoki i odwołać się do nich z aplikacji, możesz użyć wspólnej w następujący sposób:
- Zdefiniuj widok w pliku układu i przypisz mu unikalny identyfikator, na przykład
następujący przykład:
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>
- utworzyć instancję obiektu widoku i przechwycić ją z układu,
zwykle w
onCreate()
zgodnie z poniższym przykładem:Kotlin
val myButton: Button = findViewById(R.id.my_button)
Java
Button myButton = (Button) findViewById(R.id.my_button);
Definiowanie identyfikatorów obiektów widoku jest ważne przy tworzeniu
RelativeLayout
W układzie względnym widoki równorzędne mogą definiować swój układ względem innego
widoku równorzędnego, do którego odwołuje się unikalny identyfikator.
Identyfikator nie musi być unikalny w całym drzewie, ale musi tylko w obrębie objętej wyszukiwaniem. Często składa się z całej więc postaraj się, by była unikalna, gdy tylko jest to możliwe.
Parametry układu
Definicja atrybutów układu XML o nazwie layout_something
dla parametrów układu View
, które są odpowiednie dla parametru
ViewGroup
, w których się znajduje.
Każda klasa ViewGroup
implementuje zagnieżdżoną klasę, która rozszerza
ViewGroup.LayoutParams
Ta podklasa zawiera typy właściwości, które definiują rozmiar i pozycję każdej z nich
widoku podrzędnego, odpowiednio do danej grupy. Jak widać na ilustracji 2, wydawca nadrzędny
grupa widoków definiuje parametry układu dla każdego widoku podrzędnego, w tym widoku podrzędnego
grupę widoków.
Każda podklasa LayoutParams
ma własną składnię ustawień
. Każdy element podrzędny musi definiować element LayoutParams
, który jest
odpowiednie dla jej elementu nadrzędnego, choć może również definiować inne
LayoutParams
dla własnych dzieci.
Wszystkie grupy widoków danych uwzględniają szerokość i wysokość za pomocą parametru layout_width
i layout_height
, a każdy widok jest wymagany do ich zdefiniowania. Wiele
LayoutParams
mają opcjonalne marginesy i obramowania.
Możesz podać szerokość i wysokość z dokładnym pomiarem, ale nie musi często robią to samo. Częściej używa się jednej z tych stałych do ustawiania wartości parametru szerokość lub wysokość:
wrap_content
: informuje widok, aby zmienić rozmiar na wymiarów wymaganych przez jej treść.match_parent
: informuje, że widok ma być tak duży jak jego element nadrzędny zezwala na dostęp do wybranych grup.
Ogólnie nie zalecamy określania szerokości i wysokości układu za pomocą
bezwzględne jednostki, takie jak piksele. Lepszym podejściem jest stosowanie pomiarów względnych,
takie jak jednostki pikseli niezależne od gęstości (dp), wrap_content
lub
match_parent
, ponieważ pomaga w prawidłowym wyświetlaniu aplikacji na
różnych rozmiarów ekranów urządzeń. Akceptowane typy pomiarów są zdefiniowane w
Zasób układu.
Pozycja układu
Widok ma prostokątną geometrię. Ma lokalizację, wyrażoną jako parę współrzędne left i top oraz dwa wymiary, wyrażone jako szerokości i wysokości. Jednostką lokalizacji i wymiarów jest piksel.
Aby pobrać lokalizację widoku, wywołaj te metody
getLeft()
oraz
getTop()
Pierwszy zwraca współrzędną lewą (x) prostokąta reprezentującego
widoku. Ten drugi zwraca współrzędną górną (y) prostokąta
reprezentujący widok. Te metody zwracają lokalizację widoku w odniesieniu do
jego elementu nadrzędnego. Jeśli na przykład getLeft()
zwraca wartość 20, oznacza to, że para klucz-wartość
znajduje się 20 pikseli na prawo od lewej krawędzi
elementu nadrzędnego.
Istnieją też wygodne metody, które pozwalają uniknąć zbędnych obliczeń:
mianowicie
getRight()
oraz
getBottom()
Te metody zwracają współrzędne prawej i dolnej krawędzi
reprezentujący widok. Na przykład dzwonienie pod numer getRight()
to
podobnie do tego obliczenia: getLeft() + getWidth()
.
Rozmiar, dopełnienie i marginesy
Rozmiar widoku jest wyrażony za pomocą szerokości i wysokości. Widok składa się z 2 par szerokości i wysokości.
Pierwsza para ma nazwę mierzona szerokość i
mierz wzrost. Te wymiary określają, jak duży widok
w elemencie nadrzędnym. Wymiary zmierzone możesz uzyskać, wywołując
getMeasuredWidth()
oraz
getMeasuredHeight()
Druga para ma nazwy width i height. Czasami
szerokość rysunku i wysokość rysowania. Wymiary te definiują
rzeczywisty rozmiar widoku na ekranie, w czasie rysowania i po układzie. Te
mogą, ale nie muszą, różnić się od zmierzonej szerokości i wysokości. Ty
może uzyskać szerokość i wysokość, wywołując
getWidth()
oraz
getHeight()
Przy pomiarze wymiarów widok uwzględnia jego dopełnienie. Dopełnienie
jest wyrażony w pikselach dla lewej, górnej, prawej i dolnej części widoku.
Możesz użyć dopełnienia, aby odsunąć zawartość widoku o określoną liczbę
pikseli. Na przykład dwukrotne dopełnienie po lewej stronie przesuwa treść widoku o dwa piksele.
na prawo od lewej krawędzi. Dopełnienie możesz ustawić za pomocą
setPadding(int, int, int, int)
i wysyłanie do niej zapytań za pomocą wywołania
getPaddingLeft()
,
getPaddingTop()
,
getPaddingRight()
,
oraz
getPaddingBottom()
.
Chociaż widok może definiować dopełnienie, nie obsługuje on marginesów. Pamiętaj jednak:
grupy widoków danych obsługują marginesy. Zobacz
ViewGroup
i
ViewGroup.MarginLayoutParams
.
Więcej informacji o wymiarach znajdziesz w artykule Wymiar.
Oprócz automatycznego ustawiania marginesów i dopełnienia, w układach XML, jak widać w tym przykładzie:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:padding="8dp" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:paddingBottom="4dp" android:paddingEnd="8dp" android:paddingStart="8dp" android:paddingTop="4dp" android:text="Hello, I am a Button" /> </LinearLayout>
W poprzednim przykładzie widać zastosowane marginesy i dopełnienie.
TextView
ma równomierne marginesy i dopełnienie dookoła.
Button
pokazuje, jak stosować je niezależnie w
krawędzie.
Popularne układy
Każda podklasa klasy ViewGroup
zapewnia unikalny sposób
wyświetlanie zagnieżdżonych widoków. Najbardziej elastyczny typ układu,
który zapewnia najlepsze narzędzia
do utrzymywania płytkiej hierarchii układu
ConstraintLayout
Oto kilka popularnych typów układów wbudowanych w Androida. platformy.
Umieszcza elementy podrzędne w jednym poziomym lub pionowym wierszu i tworzy pasek przewijania, jeśli okno jest dłuższe niż długość ekranu.
Tworzenie list dynamicznych
Jeśli zawartość układu jest dynamiczna lub nie została wcześniej określona, możesz
należy użyć funkcji
RecyclerView
lub
podklasa
AdapterView
Zwykle lepszą opcją jest RecyclerView
, ponieważ wykorzystuje pamięć
skuteczniej niż AdapterView
.
Typowe układy dostępne w RecyclerView
i
AdapterView
obejmują:
RecyclerView
daje więcej możliwości
opcję
utwórz niestandardową
menedżer układu.
Wypełnianie widoku adaptera danymi
Możesz uzupełnić
AdapterView
na przykład ListView
lub
GridView
według
powiązanie instancji AdapterView
z
Adapter
,
który pobiera dane ze źródła zewnętrznego i tworzy View
reprezentujących każdy wpis danych.
Android oferuje kilka podklasy klasy Adapter
, które są przydatne
do pobierania różnych rodzajów danych i tworzenia widoków
AdapterView
Dwie najpopularniejsze adaptery to:
ArrayAdapter
- Użyj tego adaptera, gdy źródłem danych jest tablica. Domyślnie
Funkcja
ArrayAdapter
tworzy widok każdego elementu tablicy przez wywołanietoString()
przy każdym elemencie, a jego zawartość umieść w elemencieTextView
.Jeśli na przykład masz tablicę ciągów tekstowych, którą chcesz wyświetlić w
ListView
, zainicjuj noweArrayAdapter
przy użyciu konstruktora do określania układu każdego ciągu znaków i tablicy ciągu:Kotlin
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)
Java
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
Argumenty tego konstruktora są następujące:
- Twoja aplikacja
Context
- Układ zawierający
TextView
dla każdego ciągu w parametrze tablica - Tablica ciągu
Następnie zadzwoń
setAdapter()
na urządzeniuListView
:Kotlin
val listView: ListView = findViewById(R.id.listview) listView.adapter = adapter
Java
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
Aby dostosować wygląd każdego elementu, możesz zastąpić
toString()
dla obiektów w tablicy. Lub, aby utworzyć wyświetlenia każdego elementu, który nie jestTextView
– jeśli na przykład chcesz dodać atrybutImageView
dla każdego elementu tablicy – rozszerz klasęArrayAdapter
i zastąpićgetView()
aby zwracać wybrany typ widoku dla każdego elementu. - Twoja aplikacja
SimpleCursorAdapter
- Używaj tej przejściówki, jeśli dane pochodzą z usługi
Cursor
Jeśli używasz elementuSimpleCursorAdapter
, określ układ, który ma być używany poszczególne wiersze w tabeliCursor
i które kolumny w tabeliCursor
, który chcesz wstawić do widoków wybranego układu. Jeśli na przykład chcesz utworzyć listę imion i nazwisk osób oraz numerów telefonów możesz wykonać zapytanie, które zwróci liczbęCursor
zawierające po jednym wierszu na każdą osobę i kolumnach na imiona i nazwiska oraz numery. Ty a następnie utwórz tablicę ciągu znaków określającą, które kolumny zCursor
, które chcesz uwzględnić w układzie dla każdego wyniku, i liczbę całkowitą. tablica określająca odpowiednie widoki, które każda kolumna musi być umieszczone:Kotlin
val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER) val toViews = intArrayOf(R.id.display_name, R.id.phone_number)
Java
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};
Podczas tworzenia instancji
SimpleCursorAdapter
przekazuj parametr do użycia w poszczególnych wynikach, elementCursor
zawierający i te dwie tablice:Kotlin
val adapter = SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0) val listView = getListView() listView.adapter = adapter
Java
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
Następnie
SimpleCursorAdapter
tworzy widok dla każdego wiersza wCursor
przy użyciu podanego układu, wstawiając każdy z nichfromColumns
element do odpowiadającego mu elementutoViews
widok.
Jeśli w trakcie użytkowania aplikacji zmienisz dane źródłowe,
zostanie odczytany przez adapter, wywołaj
notifyDataSetChanged()
Informuje to załączony widok, że dane zostały zmienione i są odświeżane.
Obsługa zdarzeń kliknięcia
Możesz odpowiadać na zdarzenia kliknięcia każdego elementu w AdapterView
przez wdrożenie
AdapterView.OnItemClickListener
za pomocą prostego interfejsu online. Na przykład:
Kotlin
listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> // Do something in response to the click. }
Java
// Create a message handling object as an anonymous class. private OnItemClickListener messageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click. } }; listView.setOnItemClickListener(messageClickedHandler);
Dodatkowe materiały
Zobacz, jak są używane układy w Słonecznik aplikację demonstracyjną na GitHubie.