回答:
id
概要Android id
は、ビューを識別するために一般的に使用される整数です。これid
は、XML(可能な場合)およびコード(プログラムで)を介して割り当てることができます。これid
はView
、Inflater
(を使用するなどsetContentView
)によって生成されたXML定義のへの参照を取得するのに最も役立ちます。
id
介して割り当てXML
android:id="@+id/
somename の属性をビュー"
に追加します。android:id
はコードで使用するために一意 int
に割り当てられます。android:id
のint
値を参照しますR.id.
。int
はビルドごとに変わる可能性があるため、package.name / からIDをコピーしないでください。「somename」を使用してください。gen/
R.java
R.id.
id
割り当てられたPreference
は、がをPreference
生成するときに使用されませんView
。)id
コードを介して割り当てる(プログラムで)id
を使用して手動でsを設定するsomeView.setId(
);
int
正でなければなりませんが、それ以外それはあなたが望むものは何でもすることができarbitrary-される(これは恐ろしいであれば読み続けます。)id
Sの一意性XML
-割り当てられたid
は一意になります。id
は一意である必要はありませんid
は、(理論的には)が割り当てられたと競合するXML
可能性id
があります。id
するは、正しくクエリされた場合(読み続けて)は問題になりません。id
sが問題ではない場合(および理由)findViewById(int)
は、指定したビューからビュー階層全体で深さ優先で反復的に繰り返しView
、一致するで最初に見つかったものを返しますid
。id
XML定義の前に割り当てられたコードが割り当てられていない限りid
、findViewById(R.id.somename)
は常にそのようにXML定義のビューを返しますid
。ID
のViewGroup
をで定義しますid
。LinearLayout
とandroid:id="@+id/placeholder"
。ViewGroup
にView
s を入力します。id
各ビューに便利なを割り当てます。placeholder.findViewById(convenientInt);を使用してこれらの子ビューをクエリします。
View.generateViewId()
一意のIDを生成できるAPI 17が導入されました。
周りのビューへの参照を保持することを選択した場合は、それらを使用してインスタンス化し、getApplicationContext()
各参照をnullに設定してくださいonDestroy
。どうやら漏れたActivity
(それは後に破壊されている上にぶら下がっは)無駄な..です:)
android:id
コードで使用するためにXML を予約する View.generateViewId()
一意のIDを生成するAPI 17が導入されました。(これを指摘してくれたtake-chances-make-changesに感謝します。)*
ViewGroup
XMLで定義できない場合(または定義したくない場合)、IDをXMLで予約して、一意であることを確認できます。
ここで、values / ids.xmlはカスタムを定義しますid
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="reservedNamedId" type="id"/>
</resources>
次に、ViewGroupまたはViewが作成されたら、カスタムIDをアタッチできます
myViewGroup.setId(R.id.reservedNamedId);
id
例難読化の例としてわかりやすくするためid
に、舞台裏で競合がある場合に何が起こるかを調べてみましょう。
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>
競合をシミュレートするために、最新のビルドにR.id.placeholder
(@+id/placeholder
)のint
値 12
..が割り当てられているとしましょう。
次に、MyActivity.javaはいくつかの追加ビューをプログラムで(コードを介して)定義します。
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);
}
したがってplaceholder
、新しいTextView
の1 つには、id
12の!しかし、プレースホルダの子ビューをクエリする場合、これは実際には問題ではありません。
// 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);
*そんなに悪くない
findViewById
は深さ優先探索を行うため、「XMLで定義されたIDの上に割り当てられたコード割り当てIDが階層内にない限り」は技術的に正しくありません。「上」ではなく「前」です。
ids.xml
ます。そのため、カスタムIDをで定義する必要がありました。本当に任意のIDの場合は、View.generateViewId()
(API 17)を使用します。(見逃した場合は、要点を明確にしてください。)
PreferenceDialogFragmentCompat
それから継承しているようR.id
です。この方法では、IDでビューを見つけることができません。
View.setId(integer)
このためだけに使用できます。XMLでは、文字列IDを設定している場合でも、これは整数に変換されます。このため、Views
プログラムで追加する任意の(正の)整数を使用できます。
View
ドキュメントによると識別子は、このビューの階層内で一意である必要はありません。識別子は正の数でなければなりません。
したがって、任意の正の整数を使用できますが、この場合、同等のIDを持つビューがいくつか存在する可能性があります。階層内のビューを検索する場合は、いくつかのキーオブジェクトを使用してsetTagを呼び出すと便利です。
この回答のクレジット。
はい。setId(value)
任意の(正の)整数値を使用して任意のビューで呼び出し、を使用して親コンテナでそれを見つけることができますfindViewById(value)
。setId()
異なる兄弟ビューに対して同じ値で呼び出すことは有効ですがfindViewById()
、最初のビューのみが返されることに注意してください。
findViewById
既知の祖先を呼び出すことはパフォーマンス上の理由から良い考えですが、正しいIDを持つ子が存在する場合、直接の子が見つかるとは限りません。