Android oferuje zaawansowany i zaawansowany model składowy do tworzenia interfejsu użytkownika oparty na
podstawowe klasy układu
View
i
ViewGroup
Platforma ta obejmuje
różnych gotowych podklas View
i ViewGroup
– nazywanych widżetami
układów, których możesz używać do tworzenia interfejsu użytkownika.
Częściowa lista dostępnych widżetów obejmuje Button
,
TextView
,
EditText
,
ListView
,
CheckBox
,
RadioButton
,
Gallery
Spinner
, a tym bardziej specjalnym
AutoCompleteTextView
,
ImageSwitcher
,
TextSwitcher
.
Dostępne układy to:
LinearLayout
,
FrameLayout
,
RelativeLayout
,
i inne. Więcej przykładów:
Typowe układy.
Jeśli żaden z gotowych widżetów ani układów nie spełnia Twoich wymagań, możesz tworzyć własne
Podklasa View
. Jeśli chcesz wprowadzić niewielkie poprawki w istniejącym widżecie lub
układu, możesz utworzyć klasyfikację podrzędną widżetu lub układu i zastąpić jego metody.
Tworzenie własnych podklas View
zapewnia precyzyjną kontrolę nad wyglądem
funkcji elementu na ekranie. Aby zorientować się w możliwościach kontroli w widokach niestandardowych, skorzystaj z tych
co możesz dzięki nim zrobić:
-
Możesz utworzyć całkowicie renderowany niestandardowo typ
View
, na przykład „wolumin „sterowanie” renderowany z użyciem grafiki 2D, który przypomina analogowy elektroniczny element sterujący. -
Możesz połączyć grupę komponentów
View
w 1 komponent. Oto niektóre z nich: tworząc pole kombi (kombinację wyskakującej listy i pola tekstowego do wpisania), element sterujący selektorem podwójnej przestrzeni (panel lewy i prawy z listą który element znajduje się na której liście) itd. -
Możesz zastąpić sposób renderowania komponentu
EditText
na ekranie. Przykładowa aplikacja NotePad sprawdza się w przypadku tworzenia strony notatnika z liniami. - Możesz rejestrować inne zdarzenia, np. naciśnięcia klawiszy, i obsługiwać je w niestandardowy sposób, jak w przypadku gry.
W sekcjach poniżej wyjaśniamy, jak tworzyć widoki niestandardowe i używać ich w swojej aplikacji. Dla:
szczegółowe informacje na ten temat znajdziesz w
View
zajęcia.
Podstawowe podejście
Oto ogólne omówienie informacji, które musisz wiedzieć, aby utworzyć własny View
komponenty:
-
Rozszerz istniejącą klasę lub podklasę
View
o własne zajęcia. -
Zastąp niektóre metody z klasy nadrzędnej. Metody klasy superklasy, od których rozpoczyna się zastępowanie
on
, na przykład:onDraw()
,onMeasure()
, orazonKeyDown()
Jest podobny do zdarzeńon
w:Activity
lubListActivity
, które Ty dla cyklu życia i innych punktów zaczepienia funkcjonalności. - Użyj nowej klasy rozszerzenia. Po zakończeniu możesz używać nowej klasy rozszerzenia zamiast widoku, na podstawie którego zostały utworzone.
W pełni dostosowane komponenty
Możesz tworzyć w pełni dostosowane komponenty graficzne, które wyświetlają się w pobliżu. Potrzebujesz graficznego miernika VU, który wygląda jak stary wskaźnik analogowy, albo widoku tekstowego do wspólnego śpiewania. w którym odbijająca się piłka przesuwa się wzdłuż słów, gdy śpiewasz razem z urządzeniem do karaoke. Więcej informacji czego nie będą mogli wykonać wbudowane komponenty, niezależnie od tego, jak je połączysz.
Na szczęście możesz tworzyć komponenty, które wyglądają i działają w dowolny sposób – są one wyobraźnię, rozmiar ekranu i dostępną moc obliczeniową, pamiętając, że aplikacja może działać na czymś o znacznie mniejszej mocy niż komputer stacji roboczej.
Aby utworzyć w pełni dostosowany komponent, weź pod uwagę te kwestie:
-
Najbardziej ogólny widok, który możesz rozszerzyć, to
View
, więc zazwyczaj zaczynasz od rozszerzenia aby utworzyć nowy superkomponent. - Można dostarczyć konstruktor, który może pobierać atrybuty i parametry z pliku XML oraz wykorzystują takie atrybuty i parametry, jak kolor i zasięg miernika VU, czy szerokość i tłumienie drgań igły.
- Prawdopodobnie warto utworzyć własne detektory zdarzeń, akcesory właściwości i modyfikatory, a także bardziej zaawansowane zachowanie w klasie komponentu.
-
Prawie na pewno chcesz zastąpić ustawienie
onMeasure()
i prawdopodobnie konieczne będzie zastąponDraw()
, jeśli komponent ma coś wyświetlać. Choć w obu działach działanie domyślne, domyślne ustawienieonDraw()
nie wykonuje żadnych działań, a domyślneonMeasure()
zawsze ustawia rozmiar 100 x 100, którego prawdopodobnie nie chcesz używać. -
W razie potrzeby możesz też zastąpić inne metody
on
.
Rozszerzaj funkcje onDraw() i onMeasure()
Metoda onDraw()
generuje
Canvas
, za pomocą których możesz
możesz zaimplementować, co chcesz: grafikę 2D, inne standardowe lub niestandardowe komponenty, styl tekstu lub
co tylko przyjdzie Ci do głowy.
onMeasure()
bardziej się angażuje. onMeasure()
to kluczowy element
umowy renderowania między komponentem a jego kontenerem. onMeasure()
musi być
można więc zastąpić, aby uzyskać precyzyjne i wydajne raportowanie pomiarów części składowych. To jest
nieco bardziej skomplikowane przez wymagania dotyczące limitów określone przez wydawcę nadrzędnego, który jest przekazywany do
onMeasure()
, a przez wymaganie wywołania funkcji
setMeasuredDimension()
z mierzoną szerokością i wysokością po ich osiągnięciu
obliczonych. Jeśli nie wywołasz tej metody z zastąpionej metody onMeasure()
,
co daje wyjątek w momencie pomiaru.
Ogólnie wdrożenie onMeasure()
wygląda tak:
-
Zastąpiona metoda
onMeasure()
jest wywoływana wraz z informacją o szerokości i wysokości specyfikacji, które są traktowane jako wymagania dotyczące ograniczeń szerokości i wysokości stosowane pomiary.widthMeasureSpec
iheightMeasureSpec
są kodami całkowitymi reprezentującymi wymiary. Pełne omówienie rodzaju ograniczeń, których mogą wymagać te specyfikacje, można znaleźć w dokumentacji referencyjnej wView.onMeasure(int, int)
W tej dokumentacji opisano również cały proces pomiaru. -
Metoda
onMeasure()
komponentu oblicza szerokość i wysokość, które są wymagane do renderowania komponentu. Musi zachowywać zgodność z zaakceptowaną specyfikacją chociaż może ich przekroczyć. W takim przypadku rodzic może zdecydować, co zrobić, w tym przycinać, przewijać, zgłaszać wyjątek czy prosićonMeasure()
o ponowną próbę, np. z innymi specyfikacjami. -
Przy obliczaniu szerokości i wysokości wywołaj funkcję
setMeasuredDimension(int width, int height)
z obliczonym pomiarów. Jeśli tego nie zrobisz, zostanie utworzony wyjątek.
Oto podsumowanie innych standardowych metod, które platforma wywołuje w przypadku wyświetleń:
Kategoria | Metody | Opis |
---|---|---|
na podstawie trendów | Konstruktorki | Istnieje forma konstruktora, która jest wywoływana podczas tworzenia widoku na podstawie kodu. i formularz, który jest wywoływany, gdy widok zostanie powiększony z pliku układu. Druga forma analizuje i stosuje atrybuty zdefiniowane w pliku układu. |
|
Wywoływana po wyświetleniu i wszystkich jego elementach podrzędnych są powiększone z pliku XML. | |
Układ |
|
Wywoływana w celu określenia wymagań dotyczących rozmiaru dla tego widoku i wszystkich jego dzieci. |
|
Wywoływana, gdy ten widok musi przypisać rozmiar i pozycję wszystkim jego elementom podrzędnym. | |
|
Wywoływana po zmianie rozmiaru tego widoku. | |
Rysunek |
|
Wywoływane, gdy widok musi wyrenderować swoją treść. |
Przetwarzanie zdarzeń |
|
Wywoływana po wystąpieniu zdarzenia wyłączenia. |
|
Wywoływana po wystąpieniu kluczowego zdarzenia. | |
|
Wywoływane po wystąpieniu zdarzenia ruchu kulki. | |
|
Wywoływane po wystąpieniu zdarzenia ruchu na ekranie dotykowym. | |
Ostrość |
|
Wywoływane, gdy widok zyskuje lub traci ostrość. |
|
Wywoływane, gdy okno zawierające widok zyskuje lub traci fokus. | |
Dołączanie |
|
Wywoływane, gdy widok jest dołączony do okna. |
|
Wywoływane, gdy widok zostaje odłączony od jego okna. | |
|
Wywoływana po zmianie widoczności okna zawierającego widok. |
Złożone elementy sterujące
Jeśli nie chcesz tworzyć całkowicie niestandardowego komponentu, ale wolisz umieścić
z komponentu wielokrotnego użytku, który składa się z grupy dotychczasowych elementów sterujących, a następnie tworzy taki komponent.
składnika (lub złożonej kontroli) może być najlepszy. Podsumowując, niesie to ze sobą o wiele więcej
niepodzielne elementy sterujące lub widoki w logiczną grupę elementów, które można traktować jak jedną rzecz.
Na przykład pole złożone może być kombinacją jednego pola EditText
w jednym wierszu
i przyległy przycisk z dołączoną listą. Jeśli użytkownik kliknie przycisk i wybierze pozycję
listę, wypełnia pole EditText
, ale użytkownik może też coś wpisać
bezpośrednio do usługi EditText
.
Na Androidzie łatwo dostępne są 2 inne widoki: Spinner
oraz
AutoCompleteTextView
Tak czy inaczej, dobrym przykładem jest koncepcja pola kombi.
Aby utworzyć komponent złożony, wykonaj te czynności:
-
Podobnie jak w przypadku
Activity
, zastosuj metodę deklaratywnej (opartą na XML). aby utworzyć zawarte komponenty lub zagnieździć je automatycznie z poziomu kodu. zwykle punktem początkowym jest jakaśLayout
, więc utwórz klasę, która wydłużaLayout
W przypadku pola kombi możesz użyćLinearLayout
z w orientacji poziomej. Możesz zagnieździć też inne układy wewnątrz, dzięki czemu komponent złożony złożone i ustrukturyzowane. -
W konstruktorze nowej klasy wybierz parametry, których oczekuje superklasa, i przekaż je
do konstruktora klasy nadrzędnej. Następnie możesz skonfigurować pozostałe widoki do użycia
w nowym komponencie. W tym miejscu tworzysz pole
EditText
oraz z listą wyskakującą. Możesz wprowadzić do pliku XML własne atrybuty i parametry, który może wyciągać i używać konstruktora. -
Opcjonalnie możesz utworzyć detektory zdarzeń, które mogą generować zawarte widoki. Na przykład
detektor kliknięć elementu listy w celu zaktualizowania zawartości
EditText
po wybraniu listy. -
Opcjonalnie możesz utworzyć własne właściwości z akcesorami i modyfikatorami. Na przykład niech
Wartość
EditText
zostanie początkowo ustawiona w komponencie i wysłane zapytanie o jej zawartość, gdy niezbędną. -
Opcjonalnie zastąp
onDraw()
ionMeasure()
. Zwykle nie jest to konieczne, gdy: rozszerzając poleLayout
, ponieważ układ ma zachowanie domyślne, które prawdopodobnie działa dobrze. -
Opcjonalnie możesz zastąpić inne metody
on
, takie jakonKeyDown()
, na przykład aby wybrać określone metody domyślnych wartości z wyskakującej listy w polu kombi po kliknięciu określonego klawisza.
Zastosowanie Layout
jako podstawy dla elementów sterujących niestandardowych ma wiele zalet,
w tym:
- Możesz określić układ za pomocą deklaratywnych plików XML, tak jak w przypadku ekranu z aktywnością lub tworzyć widoki automatycznie i zagnieżdżać je w układzie z kodu.
-
Metody
onDraw()
ionMeasure()
oraz większość pozostałychon
działają prawidłowo, więc nie musisz ich zastępować. - Możesz szybko tworzyć dowolnie złożone widoki złożone i używać ich ponownie, jak gdyby były co najmniej jeden komponent.
Modyfikowanie dotychczasowego typu widoku
Jeśli istnieje komponent, który jest podobny do tego, co chcesz, możesz go rozszerzyć i zastąpić.
zachowanie, które chcesz zmienić. Wszystko to, co robisz, zapewnia w pełni spersonalizowany
komponentu, ale zaczynając od bardziej wyspecjalizowanej klasy w hierarchii View
,
działania, które pomogą Ci bezpłatnie.
Na przykład parametr
Notatnik
przykładowa aplikacja prezentuje wiele aspektów korzystania z platformy Android. Jedną z nich jest przedłużenie
w widoku EditText
, aby utworzyć notatnik z linią. Nie jest to idealny przykład, a interfejsy API
to może się zmienić, ale pokazuje nasze zasady.
Zaimportuj przykładowy notatnik z NotePad do Android Studio lub przejrzyj
używając podanego linku. W szczególności zobacz definicję słowa LinedEditText
w
NoteEditor.java
.
.
Oto kilka rzeczy, które warto wziąć pod uwagę w tym pliku:
-
Definicja
Klasa jest zdefiniowana w tym wierszu:
public static class LinedEditText extends EditText
LinedEditText
jest zdefiniowana jako klasa wewnętrzna w elemencieNoteEditor
aktywności, ale jest ona publiczna, więc można z niej korzystać jakoNoteEditor.LinedEditText
spoza klasyNoteEditor
.Poza tym
LinedEditText
tostatic
, co oznacza, że nie generuje tak zwanych „metod syntetycznych”, który umożliwia mu dostęp do danych z klasy nadrzędnej. Oznacza to, że działa jako osobna klasa, a nie coś ściśle powiązanego z funkcjąNoteEditor
. Jest to bardziej przejrzysty sposób tworzenia klas wewnętrznych, jeśli nie potrzebują dostępu do stanu z poziomu klasa zewnętrzna. Wygenerowana klasa jest mała i umożliwia łatwe korzystanie z niej zajęcia.LinedEditText
rozszerza widokEditText
, którego zakres można dostosować tę sprawę. Gdy skończysz, nowe zajęcia mogą zastąpić zwykłeEditText
widok. -
Inicjowanie klasy
Jak zawsze, pierwszy z nich jest super. To nie jest domyślny konstruktor, ale z parametrami. Element
EditText
jest tworzony z tymi parametrami, gdy jest nadwyżki z pliku układu XML. Konstruktor musi je wtedy pobrać i przekazać za pomocą konstruktora klasy nadrzędnej. -
Zastąpione metody
Ten przykład zastępuje tylko metodę
onDraw()
, ale może to być konieczne innych użytkowników podczas tworzenia własnych komponentów niestandardowych.W tym przykładzie zastąpienie metody
onDraw()
pozwala pomalować niebieskie linie na obszar roboczy widokuEditText
. Obszar roboczy jest przekazywany do zastąpionego elementu MetodaonDraw()
. Metodasuper.onDraw()
jest wywoływana przed funkcją . Należy wywołać metodę klasy nadrzędnej. W tym przypadku wywołaj go na końcu po i narysujesz linie, które chcesz uwzględnić. -
Komponent niestandardowy
Masz już komponent niestandardowy, ale jak go wykorzystać? W przykładowym formacie NotePad funkcja jest używany bezpośrednio z układu deklaratywnego, więc spójrz na
note_editor.xml
w:res/layout
. folder:<view xmlns:android="http://schemas.android.com/apk/res/android" class="com.example.android.notepad.NoteEditor$LinedEditText" android:id="@+id/note" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:padding="5dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:gravity="top" android:textSize="22sp" android:capitalize="sentences" />
Komponent niestandardowy jest tworzony w pliku XML jako widok ogólny, a klasa została określona. korzystając z pełnego pakietu. Do zdefiniowanej przez Ciebie klasy wewnętrznej odwołuje się funkcja Zapis
NoteEditor$LinedEditText
, który jest standardowym sposobem określania obiektu wewnętrznego w języku programowania Java.Jeśli komponent widoku niestandardowego nie jest zdefiniowany jako klasa wewnętrzna, możesz zadeklarować widok z nazwą elementu XML i wykluczyć atrybut
class
. Dla: przykład:<com.example.android.notepad.LinedEditText id="@+id/note" ... />
Zwróć uwagę, że klasa
LinedEditText
jest teraz oddzielnym plikiem klas. Gdy jest zagnieżdżona w klasieNoteEditor
, ta metoda nie działa.Pozostałe atrybuty i parametry w definicji to te, które są przekazywane do parametru niestandardowego do konstruktora komponentów, a potem do konstruktora
EditText
, więc to te same parametry, co w widokuEditText
. Możesz dodać za pomocą własnych parametrów.
Tworzenie komponentów niestandardowych jest tak skomplikowane, jak to konieczne.
Bardziej zaawansowany komponent może zastąpić jeszcze więcej metod on
i wprowadzić jego
własnych metod pomocniczych, zasadniczo dostosowując właściwości i działanie. Jedynym ograniczeniem jest
wyobraźnię i do czego potrzebny jest komponent.