回答:
id概要Android idは、ビューを識別するために一般的に使用される整数です。これidは、XML(可能な場合)およびコード(プログラムで)を介して割り当てることができます。これidはView、Inflater(を使用するなどsetContentView)によって生成されたXML定義のへの参照を取得するのに最も役立ちます。
id介して割り当てXMLandroid:id="@+id/somename の属性をビュー"に追加します。android:idはコードで使用するために一意 intに割り当てられます。android:idのint値を参照しますR.id.。intはビルドごとに変わる可能性があるため、package.name / からIDをコピーしないでください。「somename」を使用してください。gen/R.javaR.id.id割り当てられたPreferenceは、がをPreference生成するときに使用されませんView。)idコードを介して割り当てる(プログラムで)idを使用して手動でsを設定するsomeView.setId();int正でなければなりませんが、それ以外それはあなたが望むものは何でもすることができarbitrary-される(これは恐ろしいであれば読み続けます。)idSの一意性XML-割り当てられたidは一意になります。idは一意である必要はありませんidは、(理論的には)が割り当てられたと競合するXML可能性idがあります。idするは、正しくクエリされた場合(読み続けて)は問題になりません。idsが問題ではない場合(および理由)findViewById(int)は、指定したビューからビュー階層全体で深さ優先で反復的に繰り返しView、一致するで最初に見つかったものを返しますid。idXML定義の前に割り当てられたコードが割り当てられていない限りid、findViewById(R.id.somename)は常にそのようにXML定義のビューを返しますid。IDのViewGroupをで定義しますid。LinearLayoutとandroid:id="@+id/placeholder"。ViewGroupにViews を入力します。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に感謝します。)*
ViewGroupXMLで定義できない場合(または定義したくない場合)、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 つには、id12の!しかし、プレースホルダの子ビューをクエリする場合、これは実際には問題ではありません。
// 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を持つ子が存在する場合、直接の子が見つかるとは限りません。