Jak działa „? Android: attr / ActivatedBackgroundIndicator”?

86

Szukałem, jak podświetlić wybrany element na liście podczas wyświetlania kontekstowego paska działań dla zaznaczenia, a rozwiązaniem, które znalazłem, było ustawienie android:backgroundatrybutu mojego układu wiersza xml na "?android:attr/activatedBackgroundIndicator".

Jak to jednak działa?

  1. jaki jest mechanizm?
  2. co oznaczają elementy składni, takie jak „?”, „attr”, „ActivatedBackgroundIndicator”?
  3. gdzie jest zdefiniowane znaczenie „ActivatedBackgroundIndicator”?
jrharshath
źródło

Odpowiedzi:

221

Jeśli masz nastrój kryminalistyki, oto jak kopać i dowiedzieć się, co się dzieje.

android:background="?android:attr/activatedBackgroundIndicator"?

Intuicyjnie oznacza to ustawienie tła do rysowania.

Ale rozłóżmy to dalej, aby zobaczyć, jak dojdziemy do naszej tajemniczej narysowanej postaci.

Mówiąc dokładniej, oznacza to „ustaw atrybut tła na to, do czego odwołuje się atrybut„ activBackgroundIndicator ” w bieżącym motywie .

Jeśli rozumiesz „odnosi się do aktualnego tematu”, to w zasadzie zrozumiałeś wszystko, co dzieje się za okładkami.

Zasadniczo ActivatedBackgroundIndicator nie jest faktycznym rysunkiem, ale odniesieniem do rysowalnego . Gdzie właściwie jest zdefiniowany atrybut „activBackgroundIndictor”?

Jest zdefiniowany w katalogu sdk w nazwie pliku attrs.xml . Na przykład:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ attrs.xml

Jeśli otworzysz ten plik, otrzymasz oświadczenie w następujący sposób:

<attr name="activatedBackgroundIndicator" format="reference" />

attrs.xml to miejsce, w którym deklarujesz wszystkie atrybuty, których będziesz później używać w swoim pliku widoku XML. Zauważ, że deklarujemy atrybut i jego typ, a nie przypisujemy tutaj wartości .

Rzeczywista wartość jest przypisywana w plikach themes.xml . Ten plik znajduje się pod adresem:

path_to_android_sdk / platform / android-17 / data / res / values ​​/ themes.xml

Jeśli otworzysz ten plik, zobaczysz wiele definicji w zależności od używanego motywu . Na przykład, oto definicje motywów nazwanych odpowiednio Theme, Theme.Light, Theme.Holo, Theme.Holo.Light:

<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_dark</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>

Teraz mamy nasze tajemnicze przedmioty do rysowania. Jeśli wybierzesz pierwszy, zostanie on zdefiniowany w folderze do rysowania pod adresem:

path_to_android_sdk / platform / android-17 / data / res / drawable / Activated_background.xml

Jeśli otworzysz ten plik, zobaczysz definicję rysunku, która jest ważna dla zrozumienia, co się dzieje.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
    <item android:drawable="@color/transparent" />
</selector>

Tutaj definiujemy element rysunkowy z dwoma stanami - domyślnym stanem jest po prostu przezroczyste tło, a jeśli stan to „state_activated”, to naszym elementem do rysowania jest „list_selector_background_selected”.

zobacz ten link, aby uzyskać podstawowe informacje na temat przedmiotów do rysowania i stanów.

„list_selector_background_selected” to plik png z 9 poprawkami, który znajduje się w folderze drawable-hdpi.

Teraz możesz zobaczyć, dlaczego zdefiniowaliśmy activeBackgroundIndicator jako odniesienie, zamiast bezpośredniego łączenia z plikiem do rysowania - pozwala to wybrać odpowiedni element do rysowania w zależności od motywu.

numan salati
źródło
3
Jedna odpowiedź, by wszystkimi rządzić. Więc w zasadzie gdyby ktoś miał stworzyć XML z tymi samymi selektorami, mógłby stworzyć swój własny „activeBackgroundIndicator”?
Gee.E
1
dokładnie - możesz przedefiniować go w swoim niestandardowym motywie. xml b / c jest to atrybut odniesienia.
numan salati
Ta odpowiedź pomogła mi dowiedzieć się, jak ustawić niestandardowy element do rysowania w elemencie listy szuflady nawigacji.
Tastybrownies
To świetny zasób do rozpoczęcia pracy nad niestandardowymi selectorpracami przy użyciu rysunków. Po przeczytaniu tego użyłem Style Attribute Docs, aby wypełnić pozostałe elementy.
Maurizio
1
Czy możesz podać przykład, jak zastąpić ten wskaźnik tła? Mój nie działa: / <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar"> <item name = "android: activBackgroundIndicator"> @ drawable / Activated_background </item> </style> Activated_background.xml : <selector xmlns: android = " schemas.android.com/apk/res/android "> <element android: state_activated = "true" android: drawable = "@ color / yellow" /> <item android: drawable = "@ android: color / transparent "/> </selector>
vandus
13

W pewnym momencie też się nad tym zastanawiałem. Duża ilość zasobów Androida wygląda jak czarna skrzynka i nie widzi ich bezpośrednio. Być może brakuje mi ich gdzieś, ale nie mogę ich znaleźć w kodzie źródłowym SDK. Oto, co wiem.

  • android:background weźmie do rysowania.
  • Składnia jest w stylu

    Musi być odniesieniem do innego zasobu w postaci „@ [+] [pakiet:] typ: nazwa” lub do atrybutu motywu w postaci „? [Pakiet:] [typ:] nazwa”

W tym przypadku ?oznacza to spojrzenie na motyw w pakiecie androidi jest to typ, w attrktórym znajduje się nazwa activatedBackgroundIndicator.

Powinieneś mieć również dostęp do tego w kodzie związanym z android.R.attr.activatedBackgroundIndicator.

Listę attrwłaściwości systemu Android można znaleźć pod adresem R.attr

  • activatedBackgroundIndicator jest zdefiniowany do rysowania w systemie Android 3.0+ jako

    Do rysowania używane jako tło dla aktywowanych elementów.

Jest to po prostu standardowy element zdefiniowany w systemie operacyjnym. Nie mogę znaleźć w źródle Androida, ale tutaj jest link do dokumentacji. ActivatedBackgroundIndicator

Kościół
źródło
5

Jest to forma przypisywania wartości z tematu. Wartość nie jest technicznie znana podczas kompilacji zasobów, ponieważ wartości motywu mogą nie być znane w tym momencie. Zamiast tego wartość jest określana w czasie wykonywania na podstawie rzeczywistego motywu pobranego z (najczęściej) ContextThemeWrapper.

Zapewnia to sposób ponownego wykorzystania wartości zasobów. Nie mówię tu o wydajności, ale raczej o organizacji i utrzymaniu. Atrybut działa tak, jakby był zmienną z obietnicą, że zachowa rzeczywistą wartość w czasie wykonywania.

Takie podejście pozwala również na większą personalizację - zamiast zakodowania na stałe wartości np. Tła okna, które można rysować, pobiera on rzeczywisty możliwy do rysowania z motywu, podając wybrany atrybut jako klucz. Pozwala to zastąpić wartość tego atrybutu. Wystarczy:

  1. Stwórz swój własny motyw (co jest po prostu fantazyjną nazwą zasobu „stylu”), najczęściej pochodzącym od jednego z domyślnych motywów.
  2. Podaj własną wartość dla danego atrybutu.

Platforma automatycznie użyje Twojej wartości, pod warunkiem, że określisz motyw dla działania lub aplikacji. Robisz to tak, jak opisano w pytaniu. Ogólna składnia odniesień do atrybutów motywu jest opisana tutaj: Odwoływanie się do atrybutów stylu . Znajdziesz tam również przykład i opis całego mechanizmu.

Edytować

Należy zwrócić uwagę na faktyczne nazwy atrybutów i ich istnienie w różnych wersjach platform. Dość często zdarza się, że nowe atrybuty są wprowadzane w kolejnych wersjach platform - na przykład niektóre zostały dodane w wersji 3.0 w celu stylizacji ActionBar.

Nazwy atrybutów należy traktować jako część interfejsu API - innymi słowy, są one częścią umowy, której możesz używać. Jest to bardzo podobne do klas i ich sygnatur - używasz LocationManagerclass w celu uzyskania ostatniej lokalizacji urządzenia, ponieważ wiesz z jakiegoś źródła (tutoriale, referencje, oficjalne przewodniki itp.), Jaki jest cel tej klasy. Podobnie nazwy atrybutów i ich przeznaczenie są (czasem dobrze, czasem mizernie) zdefiniowane w dokumentacji platformy Android.

andr
źródło
2

Aktualizacja: dostępna jest bardziej szczegółowa wersja przewodnika po interfejsie API, więc chciałbym ją zacytować.

Zasób atrybutu stylu umożliwia odwołanie się do wartości atrybutu w aktualnie stosowanym motywie. Odwołanie do atrybutu stylu umożliwia dostosowanie wyglądu elementów interfejsu użytkownika przez nadanie im stylu zgodnego ze standardowymi odmianami dostarczanymi przez bieżący motyw, zamiast dostarczania wartości zakodowanej na stałe. Odwołanie do atrybutu stylu zasadniczo mówi: „użyj stylu zdefiniowanego przez ten atrybut w bieżącym motywie”.

Aby odwołać się do atrybutu stylu, składnia nazwy jest prawie identyczna z normalnym formatem zasobu, ale zamiast symbolu at (@) użyj znaku zapytania (?), A część dotycząca typu zasobu jest opcjonalna. Na przykład: `

Oryginalna odpowiedź:

Numan salati już zaoferował doskonałą odpowiedź, ale nie odniósł się do „?” składnia. Oto cytat z przewodnika API Accessing Resources

Aby odwołać się do atrybutu stylu, składnia nazwy jest prawie identyczna z normalnym formatem zasobu, ale zamiast symbolu at (@) użyj znaku zapytania (?), A część dotycząca typu zasobu jest opcjonalna. Na przykład:

? [<nazwa_pakietu>:] [<typ_zasobu> /] <nazwa_zasobu>

Teng-pao Yu
źródło