Jak mogę programowo przypisać identyfikator do widoku?

W pliku XML możemy przypisać ID do widoku jak android:id="@+id/something", a następnie wywołać findViewById(), ale podczas tworzenia widoku programowo, jak przypisać ID?

Myślę, że {[2] } to nie to samo co domyślne przypisanie. setId() jest extra.

Czy ktoś może mnie poprawić?
Author: Karu, 2011-12-11

3 answers

Android id Przegląd

Android {[5] } jest liczbą całkowitą powszechnie używaną do identyfikacji widoków; to id może być przypisane za pomocą XML (jeśli to możliwe) i za pomocą kodu (programowo.) id jest najbardziej przydatny do uzyskiwania referencji dla zdefiniowanych w XML Views wygenerowanych przez Inflater (np. przez użycie setContentView.)

Assign id via XML

  • Dodaj atrybut android:id="@+id/ somename" do swojego widoku.
  • po zbudowaniu aplikacji, android:id zostanie przypisany a unique int do użycia w kodzie.
  • odwołaj się do swojej android:id'S int wartość w kodzie używając "R.id. somename " (w rzeczywistości stała.)
  • to int może się zmienić z build na build więc nigdy nie kopiuj id z gen/ package.name / R.java, wystarczy użyć "R.id.somename".
  • (również id przypisany do Preference W XML nie jest używany, gdy Preference generuje swój View.)

Przypisz id za pomocą kodu (programowo)

  • Ręczne ustawianie ids za pomocą someView.setId(int );
  • int musi być pozytywny, ale poza tym arbitralny - może być cokolwiek chcesz (Czytaj dalej, jeśli jest to przerażające.)
  • na przykład, jeśli tworzysz i numerujesz kilka widoków reprezentujących elementy, możesz użyć ich numeru elementu.

Unikalność id s

  • XML-przypisane id s będą unikalne.
  • Code-assigned id s do not muszą być unikalne
  • kod-przypisany id s może (teoretycznie) kolidować z XML - przypisany id s.
  • te sprzeczne id s nie będzie miało znaczenia, czy zapytano poprawnie (Czytaj dalej).

Kiedy (i dlaczego) sprzeczne ids nie ma znaczenia

  • findViewById(int) będzie powtarzał głębokość-pierwsza rekurencyjnie przez hierarchię widoku z widoku, który określisz i zwróci pierwszą View, którą znajdzie z dopasowanym id.
  • dopóki nie ma w zależności od tego, która z tych wartości jest zdefiniowana przez XML, w hierarchii, findViewById(R.id.somename) zawsze będzie zwracany Widok zdefiniowany przez XML, tak więc id ' d.

Dynamiczne tworzenie widoków i przypisywanie IDs

  • w layout XML zdefiniuj pusty ViewGroup za pomocą id.
  • np. LinearLayout Z android:id="@+id/placeholder".
  • Użyj kodu, aby wypełnić miejsce ViewGroup View s.
  • jeśli potrzebujesz lub chcesz, Przypisz dowolne ids, które są wygodne dla każdego widok.
  • Odpytywaj te widoki potomne za pomocą symbolu zastępczego.findViewById(ujednoznacznienie);

  • API 17 wprowadziło View.generateViewId(), które pozwala na wygenerowanie unikalnego identyfikatora.

Jeśli zdecydujesz się zachować odniesienia do swoich widoków wokół , upewnij się, że tworzysz ich instancje za pomocą getApplicationContext() i ustaw każde odniesienie na null w onDestroy. Najwidoczniej przeciekanie Activity (wiszące na nim po zniszczeniu is) jest marnotrawstwem.. :)

Zarezerwuj XML android:id do użycia w kodzie

wprowadzono API 17 View.generateViewId() który generuje unikalny identyfikator. (dzięki take-chances-make-changes za zwrócenie na to uwagi.)*

Jeśli twój ViewGroup nie może być zdefiniowany przez XML (lub nie chcesz, aby był), możesz zarezerwować id za pomocą XML, aby upewnić się, że pozostanie unikalny:

Tutaj, wartości / ids.xml definiuje Niestandardowy id:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="reservedNamedId" type="id"/>
</resources>

Następnie po utworzeniu ViewGroup lub View można dołączyć custom id

myViewGroup.setId(R.id.reservedNamedId);

Conflicting id example

Dla jasności na przykładzie zaciemniania, przyjrzyjmy się, co się dzieje, gdy za kulisami występuje konflikt.

Layout / mylayout.xml

<?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" >
    <LinearLayout
        android:id="@+id/placeholder"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
</LinearLayout>

aby zasymulować konflikt, powiedzmy, że nasza najnowsza kompilacja przypisana R.id.placeholder(@+id/placeholder) an int wartość 12..

Następna, Moja Aktywność.java definiuje niektóre widoki programowo (za pomocą kodu):

int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
    TextView tv = new TextView(this.getApplicationContext());
    // One new TextView will also be assigned an id==12:
    tv.setId(i);
    placeholder.addView(tv);
}

Więc placeholder i jeden z naszych nowych TextViewoba mają id z 12! Ale nie jest to tak naprawdę problem, jeśli zapytamy o widoki potomne placeholdera:

// Will return a generated TextView:
 placeholder.findViewById(12);

// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12: 
Activity.this.findViewById(12);

*nie tak źle

 492
Author: CodeShane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-05 23:24:09

Możesz po prostu użyć View.setId(integer) do tego. W XML, nawet jeśli ustawiasz identyfikator łańcucha znaków, zostanie on przekonwertowany na liczbę całkowitą. Dzięki temu możesz użyć dowolnej (dodatniej) liczby całkowitej dla Views, którą dodajesz programowo.

Zgodnie z View dokumentacją

Identyfikator nie musi być unikalny w hierarchii tego widoku. Identyfikator powinien być liczbą dodatnią.

Więc możesz użyć dowolnej dodatniej liczby całkowitej, ale w tym sprawa tam może być kilka widoków o równoważnym id ' s. Jeśli chcesz wyszukać jakieś widok w hierarchii wywołanie setTag z niektórymi kluczowymi obiektami może być poręczne.

Napisy do tej odpowiedzi.

 6
Author: Sander van't Veer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:48

Tak, możesz wywołać setId(value) w dowolnym widoku z dowolną (dodatnią) liczbą całkowitą, a następnie znaleźć ją w kontenerze nadrzędnym za pomocą findViewById(value). Zauważ, że ważne jest wywołanie setId() z tą samą wartością dla różnych widoków rodzeństwa, ale findViewById() zwróci tylko pierwszy.

 5
Author: dmon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-10 23:47:22