Jak określić identyfikator, gdy używa się w pliku XML układu


117

W moim pliku XML układu zawarłem inny plik XML układu (każdy z innym identyfikatorem Androida).

<include layout="@layout/view_contact_name" android:id="+id/test1"/>
<include layout="@layout/view_contact_name" android:id="+id/test2"/>

Ale kiedy uruchamiam go w emulatorze i uruchamiam Hierarchy Viewer, każdy układ nadal pokazuje „NO_ID”, aw moim kodzie mam findViewById(R.id.test1)i findViewById(R.id.test2)oba zwracają wartość null.

Czy ktoś może mi pomóc z moim problemem?


6
W Twoich identyfikatorach brakuje @symbolu.
AutonomousApps,

Odpowiedzi:


288

Określ identyfikator w <include>

<include layout="@layout/test" android:id="@+id/test1" />

Następnie użyj dwóch, findViewByIdaby uzyskać dostęp do pól w układzie

View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);

Korzystając z tego podejścia, możesz uzyskać dostęp do dowolnego pola w dowolnym pliku dołączonym.


18
Ta metoda zwraca mi wartość null dla obiektu test1View.
Nirav Shah

4
Naprawdę nie widzę różnicy, czy możesz wyjaśnić?
Goddchen

30
Dowiedziałem się, że jeśli układ, który dołączyliśmy, korzysta z funkcji merge, to nie pomoże. Ale w przypadku, gdy scalanie nie jest używane, działa to.
Zlatko,

@Zlatko Tak, i to nie może działać mergenawet w teorii, ponieważ efektem włączenia mergenie jest pojedynczy widok, ale ich kilka. Więc jest ok.
Nazwa wyświetlana

1
Będzie to działać tylko w przypadku, gdy scalanie nie jest używane. W przypadku scalenia nie jest to możliwe, jak określono tutaj: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

Dowiedziałem się, że jeśli używasz <merge>tagu w swoim układzie include, to identyfikator transferów include do tagu scalającego, który nie jest rzeczywistym widokiem.

Więc albo usuń scalanie, albo zastąp je jakimś układem.

Tor Norbye napisał :

<include>Tag nie jest prawdziwy widok, więc findByView nie będzie go znaleźć. Atrybut @id (i wszelkie inne atrybuty ustawione w tagu include) zostanie zamiast tego zastosowany do tagu głównego dołączonego układu. Więc twoja aktywność.getView (R.id.included1) powinna być w rzeczywistości <TextView>sobą.


3
Dobry. Usuwam tag scalający i zaczyna działać, ale moje pytanie brzmi: jakie jest użycie tagu scalającego, jeśli którykolwiek zawiera układ działa bez niego?
Ankur Chaudhary

35

Romain Guy wskazuje , że można zastąpić identyfikator dołączonego układu, umieszczając android:idatrybut wewnątrz <include>tagu.

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />

1
To jest poprawne. Sposobem na odwołanie się do elementu głównego w dołączonym pliku układu jest id podany w tagu „include” (chyba że nie jest podany).
Tom R

1
ID w <include> = identyfikator roota w dołączonym układzie
Fadils,

Wydaje mi się, że jeśli najpierw ustawię identyfikator (w tagu include zastępuje identyfikator z dołączonego układu, prawda?), Będę miał początkowo tag nagłówkowy `` @ + id / cell1 '', a następnie układ = ' @ layout / workspace_screen 'nadpisze android: id ponownie z identyfikatorem dołączonego układu. Odpowiedzi @Ron Romero mają dla mnie więcej sensu.
Neon Warge

14

Myślę, że najlepsza odpowiedź pomija najważniejszy punkt i może wprowadzać ludzi w błąd, myśląc, że <include/>tag tworzy widok, który przechowuje zawartość dołączaną.

Kluczową kwestią jest to, że identyfikator include jest przekazywany do widoku głównego pliku układu dołączenia.

Co oznacza, że:

// activity_main.xml
<include layout="@layout/somelayout" android:id="@+id/someid"/>

// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

Staje się tym:

// activity_main.xml
<ImageView
    android:id="@+id/someid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

4

tak jest, ale uważaj, gdy układ wstawiony w pole dołączania jest niestandardowym i chcesz uzyskać dostęp do tego układu głównego. Ten układ w tym przypadku @ layout / test test jest w rzeczywistości zwracany w pierwszym wierszu.

test test1View = (test)findViewById(R.id.test1);


2

Problem polega na tym, że próbujemy użyć identyfikatora, który nie jest zadeklarowany w bieżącym pliku układu. Zamiast ponownie deklarować, id można po prostu odnieść za pomocą @+id/. Jeśli zmienisz oryginalną nazwę identyfikatora za pomocą Android Studio, nastąpi to również w dołączonym układzie.

<include layout="@layout/toolbar"/>

<TextView
    android:id="@+id/txt_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    **android:layout_below="@+id/toolbar"**
    android:layout_marginTop="16dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"/>

2

W przypadku użycia <RecyclerView>znajdź id of <include>przy użyciu wystąpienia zawyżonego widoku, inaczej zwróci wartość null .

public class ViewHolder extends RecyclerView.ViewHolder {

        private mTextView;

        public ViewHolder(View view) {
            super(view);
            View include_1 = view.findViewById(R.id.include_1);
            mTextView = (TextView) include_1.findViewById(R.id.text_id);
        }
    }

1

Jeśli ustawiłeś id na dowolny znacznik główny dołączonego układu, możesz użyć tego identyfikatora lub możesz ustawić id na dołączony układ.

Ale nie możesz ustawić id na oba, może to spowodować wyjątek.

<include layout="@layout/view_contact_name" android:id="+id/test1"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

Lub

<include layout="@layout/view_contact_name"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/llBottomMainView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

0

Mówiąc o dołączaniu, masz identyfikator w widoku głównym w dołączonym pliku układu lub w samej linii dołączania, a nie w obu. Na przykład:

<include layout="@layout/layout1" android:id="@+id/layout1"/>

Plik układu 1

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout2">

</RelativeLayout>

Powyższy przykład jest błędny, ponieważ technicznie rzecz biorąc, masz zadeklarowane dwa identyfikatory dla tego samego układu. Musisz więc wybrać, który element będzie miał identyfikator.


0

Wow, nie mogę uwierzyć, że to pytanie nie ma jeszcze właściwej odpowiedzi. To proste tagi są do niczego. Możesz zmienić tylko rzeczy, które zaczynają się od tego, android:layout_co android:idnie pasuje. Więc odpowiedź brzmi: nie możesz. Przepraszam. Zamiast tego możesz utworzyć klasę, która będzie ViewGroup, która będzie zawyżać zawarte w niej widoki, a następnie dodać ją jako tag w swoim układzie, ale to wszystko.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.