XML ファイルでは、 のようなビューに ID を割り当てて をandroid:id="@+id/something"
呼び出すことができfindViewById()
ますが、プログラムでビューを作成する場合、ID を割り当てるにはどうすればよいでしょうか?
setId()
デフォルトの割り当てと同じではないと思います。setId()
余分です。
誰でも私を修正できますか?
XML ファイルでは、 のようなビューに ID を割り当てて をandroid:id="@+id/something"
呼び出すことができfindViewById()
ますが、プログラムでビューを作成する場合、ID を割り当てるにはどうすればよいでしょうか?
setId()
デフォルトの割り当てと同じではないと思います。setId()
余分です。
誰でも私を修正できますか?
id
の概要Androidid
は、ビューを識別するために一般的に使用される整数です。これは、XML (可能な場合) およびコード(id
プログラム) を介して割り当てることができます。id
View
Inflater
setContentView
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
正でなければなりませんが、それ以外は恣意的です - それはあなたが望むものであれば何でもかまいません (これが恐ろしい場合は読み続けてください.)id
s の一意性XML
-割り当てられid
た は一意になります。id
必要はありませんid
は (理論的には) -割り当てられた と競合する可能性がありXML
ますid
。id
s は、正しく照会されれば問題になりません(読み続けてください)。id
競合するs が問題にならない場合 (およびその理由)findViewById(int)
指定したビューからビュー階層を深さ優先で再帰的に反復View
し、一致する最初に見つかったものを返しますid
。id
XML 定義の前にコード割り当て が割り当てられていない限り、常に XML 定義のビューを返します。id
findViewById(R.id.somename)
id
ID
s の割り当てViewGroup
with を定義しid
ます。LinearLayout
_android:id="@+id/placeholder"
ViewGroup
にView
s を設定します。id
て、各ビューに便利な を割り当てます。placeholder.findViewById(convenientInt); を使用してこれらの子ビューをクエリします。
API 17 が導入さView.generateViewId()
れ、一意の ID を生成できるようになりました。
ビューへの参照を保持することを選択した場合は、必ず でそれらをインスタンス化し、 でgetApplicationContext()
各参照を null に設定してくださいonDestroy
。どうやら(が破壊された後にそれにぶら下がっている)リークはActivity
無駄です.. :)
android:id
コードで使用するためにXML を予約する View.generateViewId()
一意の ID を生成するAPI 17 が導入されました。(これを指摘してくれた take-chances-make-changes に感謝します。)*
XML 経由で定義できない場合ViewGroup
(または定義したくない場合) は、XML 経由で ID を予約して、ID が一意であることを確認できます。
ここで、values/ids.xmlは custom を定義します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
難読化の例を使用してわかりやすくするために、舞台裏で競合が発生した場合に何が起こるかを調べてみましょう。
レイアウト/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);
*そんなに悪くない
これには を使用できますView.setId(integer)
。XML では、文字列 ID を設定していても、これは整数に変換されます。このため、Views
プログラムで追加する任意の (正の) 整数を使用できます。
View
ドキュメントによると識別子は、このビューの階層内で一意である必要はありません。識別子は正の数でなければなりません。
したがって、任意の正の整数を使用できますが、この場合、同等の ID を持つビューがいくつか存在する可能性があります。階層内のいくつかのビューを検索する場合は、いくつかのキー オブジェクトを使用して setTag を呼び出すと便利な場合があります。
この回答へのクレジット。
はい、setId(value)
任意の(正の)整数値を使用して任意のビューを呼び出し、を使用して親コンテナーでそれを見つけることができますfindViewById(value)
。setId()
異なる兄弟ビューに対して同じ値で呼び出すことは有効ですがfindViewById()
、最初のビューのみを返すことに注意してください。