Jak zadeklarować element interfejsu użytkownika Androida za pomocą XML?
xml
android
user-interface
Casebash
źródło
źródło
Odpowiedzi:
Przewodnik dla programistów Androida zawiera sekcję Budowanie niestandardowych komponentów . Niestety, omówienie atrybutów XML obejmuje jedynie zadeklarowanie kontroli w pliku układu, a nie obsługę wartości wewnątrz inicjalizacji klasy. Kroki są następujące:
1. Zadeklaruj atrybuty w
values\attrs.xml
Zwróć uwagę na użycie nieoznaczonej nazwy w
declare-styleable
tagu. Niestandardowe atrybuty Androida, takie jakextraInformation
muszą mieć zadeklarowany typ. Tagi zadeklarowane w nadklasie będą dostępne w podklasach bez konieczności ponownego zgłaszania.2. Utwórz konstruktory
Ponieważ istnieją dwa konstruktory, które używają
AttributeSet
do inicjalizacji, wygodnie jest utworzyć osobną metodę inicjowania dla konstruktorów.R.styleable.MyCustomView
jest automatycznie generowanymint[]
zasobem, w którym każdy element jest identyfikatorem atrybutu. Atrybuty są generowane dla każdej właściwości w pliku XML poprzez dołączenie nazwy atrybutu do nazwy elementu. Na przykładR.styleable.MyCustomView_android_text
zawieraandroid_text
atrybut dlaMyCustomView
. Atrybuty można następnie pobrać zTypedArray
różnychget
funkcji. Jeśli atrybut nie jest zdefiniowany w zdefiniowanym w XML, tonull
jest zwracany. Z wyjątkiem oczywiście, jeśli typ zwracany jest prymitywem, w którym to przypadku zwracany jest drugi argument.Jeśli nie chcesz odzyskać wszystkich atrybutów, możesz ręcznie utworzyć tę tablicę. Identyfikator standardowych atrybutów Androida jest zawarty
android.R.attr
, a atrybuty tego projektu są wR.attr
.Należy pamiętać, że należy nie używać niczego
android.R.styleable
, co za tym wątku może się zmienić w przyszłości. W dokumentacji nadal znajduje się przegląd wszystkich tych stałych w jednym miejscu.3. Użyj go w plikach układu, takich jak
layout\main.xml
Dołącz deklarację przestrzeni nazw
xmlns:app="http://schemas.android.com/apk/res-auto"
do elementu xml najwyższego poziomu. Przestrzenie nazw zapewniają metodę pozwalającą uniknąć konfliktów, które czasami występują, gdy różne schematy używają tych samych nazw elementów ( więcej informacji można znaleźć w tym artykule ). Adres URL to po prostu sposób jednoznacznej identyfikacji schematów - pod tym adresem URL nie trzeba nic hostować . Jeśli wydaje się, że to nic nie robi, to dlatego, że tak naprawdę nie trzeba dodawać prefiksu przestrzeni nazw, chyba że trzeba rozwiązać konflikt.Odwołaj się do widoku niestandardowego, używając w pełni kwalifikowanej nazwy.
Próbka Android LabelView
Jeśli chcesz uzyskać pełny przykład, spójrz na przykładowy widok widoku etykiety Androida.
LabelView.java
attrs.xml
custom_view_1.xml
Jest to zawarte w
LinearLayout
atrybucie z przestrzenią nazw:xmlns:app="http://schemas.android.com/apk/res-auto"
Spinki do mankietów
źródło
Świetne referencje. Dzięki! Dodatek do tego:
Jeśli zdarzy się, że dołączasz projekt biblioteki, który zadeklarował niestandardowe atrybuty widoku niestandardowego, musisz zadeklarować przestrzeń nazw projektu, a nie bibliotekę. Na przykład:
Biorąc pod uwagę, że biblioteka ma pakiet „com.example.library.customview”, a działający projekt ma pakiet „com.example.customview”, wówczas:
Nie będzie działać (pokazuje błąd „błąd: nie znaleziono identyfikatora zasobu dla atrybutu„ newAttr ”w pakiecie„ com.example.library.customview ””):
Będzie działać:
źródło
xmlns:app="http://schemas.android.com/apk/res-auto"
Patrz komentarz 57 w code.google.com/p/android/issues/detail?id=9656Suspicious namespace: Did you mean http://schemas.android.com/apk/res-auto
res-auto
ponieważ używamy Androida Studio i Gradle. W przeciwnym razie (np. Niektóre wersje Eclipse) zwykle kończy sięlib/[your package name]
. tj.http://schemas.android.com/apk/lib/[your package name]
Dodatek do najczęściej głosowanej odpowiedzi.
uzyskaćStyledAttributes ()
Chcę dodać kilka słów na temat korzystania z metody replaceStyledAttributes () podczas tworzenia niestandardowego widoku przy użyciu wstępnie zdefiniowanych atrybutów Androida: xxx. Zwłaszcza, gdy korzystamy z TextAppearance.
Jak wspomniano w „2. Tworzenie konstruktorów”, widok niestandardowy pobiera AttributeSet podczas jego tworzenia. Główne zastosowanie możemy zobaczyć w kodzie źródłowym TextView (API 16).
Co możemy tutaj zobaczyć?
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
Zestaw atrybutów jest przetwarzany według kompozycji zgodnie z dokumentacją. Wartości atrybutów są kompilowane krok po kroku. Najpierw atrybuty są wypełniane z kompozycji, następnie wartości są zastępowane wartościami ze stylu, a na koniec dokładne wartości z XML dla specjalnej instancji widoku zastępują inne.
Tablica żądanych atrybutów -
com.android.internal.R.styleable.TextView
jest to zwykła tablica stałych. Jeśli żądamy standardowych atrybutów, możemy zbudować tę tablicę ręcznie.
Czego nie wymieniono w dokumentacji - kolejność wyników elementów TypedArray.
Po zadeklarowaniu widoku niestandardowego w pliku attrs.xml generowane są specjalne stałe dla indeksów atrybutów. I możemy wyodrębnić Wartości w ten sposób:
a.getString(R.styleable.MyCustomView_android_text)
. Ale do ręcznegoint[]
nie ma stałych. Przypuszczam, że getXXXValue (arrayIndex) będzie działał dobrze.Inne pytanie brzmi: „Jak możemy zastąpić stałe wewnętrzne i zażądać standardowych atrybutów?” Możemy użyć wartości android.R.attr. *.
Jeśli więc chcemy użyć standardowego atrybutu TextAppearance w widoku niestandardowym i odczytać jego wartości w konstruktorze, możemy zmodyfikować kod z TextView w ten sposób:
Gdzie zdefiniowano CustomLabel:
Może w jakiś sposób się mylę, ale dokumentacja Androida dotycząca metody receiveStyledAttributes () jest bardzo słaba.
Rozszerzanie standardowego komponentu interfejsu użytkownika
W tym samym czasie możemy po prostu rozszerzyć standardowy komponent interfejsu użytkownika, używając wszystkich jego zadeklarowanych atrybutów. To podejście nie jest tak dobre, ponieważ TextView na przykład deklaruje wiele właściwości. I nie będzie możliwe wdrożenie pełnej funkcjonalności w przesłoniętej funkcji onMeasure () i onDraw ().
Ale możemy poświęcić teoretycznie szerokie ponowne wykorzystanie niestandardowego komponentu. Powiedz „Wiem dokładnie, jakich funkcji będę używać” i nie udostępniaj nikomu kodu.
Następnie możemy zaimplementować konstruktor
CustomComponent(Context, AttributeSet, defStyle)
. Po wywołaniusuper(...)
wszystkie atrybuty zostaną przeanalizowane i udostępnione za pomocą metod pobierających.źródło
Wygląda na to, że Google zaktualizowało swoją stronę programisty i dodało tam różne szkolenia.
Jeden z nich dotyczy tworzenia niestandardowych widoków i można go znaleźć tutaj
źródło
Wielkie dzięki za pierwszą odpowiedź.
Jeśli chodzi o mnie, miałem tylko jeden problem. Podczas nadmuchiwania mojego widoku wystąpił błąd: java.lang.NoSuchMethodException: MyView (kontekst, atrybuty)
Rozwiązałem go, tworząc nowy konstruktor:
Mam nadzieję, że to pomoże!
źródło
Możesz dołączyć dowolny plik układu do innego pliku układu jako-
tutaj pliki układu w tagu dołączania to inne pliki układu .xml w tym samym folderze res.
źródło