1. ホーム
  2. アンドロイド

[解決済み] [Solved] プログラムでビューにIDを割り当てるには?

2022-04-22 07:54:17

質問

XMLファイルでは、ビューにIDを割り当てることができます。 android:id="@+id/something" を呼び出して findViewById() しかし、プログラム的にビューを作成する場合、どのようにIDを割り当てるのでしょうか?

私が思うに setId() は、デフォルトの割り当てと同じではありません。 setId() は余分です。

どなたか訂正していただけませんか?

どのように解決するのですか?

アンドロイド id 概要

あるアンドロイド id はビューを識別するためによく使われる整数で、この id は、XML (可能な場合) およびコード (プログラム) で割り当てることができます。 id は、XMLで定義された View によって生成された Inflater (を使用するなどして)。 setContentView .)

アサイン id を経由して XML

  • の属性を追加します。 android:id="@+id/ ソーメン " をビューに追加します。
  • アプリケーションがビルドされると android:id が割り当てられます。 ユニーク int をコードで使用します。
  • を参照してください。 android:id 's int の値を、" を使ってコード化します。 R.id. somename"(事実上の定数。)
  • これ int は、ビルドごとに変更することができます だから IDをコピーしない から gen/ パッケージ.名/ R.java のように、" を使用するだけです。 R.id. somename"です。
  • (また id に割り当てられた Preference は、XML では使用されません。 Preference は、その View .)

アサイン id コードを介して(プログラム的に)

  • 手動で設定する id を使用して someView.setId( イント );
  • int は正でなければならないが、それ以外は任意である-好きなものにできる(これが怖いなら読み続けてくれ)。
  • 例えば、アイテムを表す複数のビューを作成して番号を付ける場合、そのアイテム番号を使用することができます。

の一意性 id s

  • XML -アサイン id は一意になります。
  • コード指定 id を行う。 ない 一意でなければならない
  • コード指定 id と競合する可能性があります。 XML -割り当てられた id s.
  • これらの相反する id は、正しくクエリされれば問題ありません。 (続きを読む) .

コンフリクトする場合(とその理由 id は重要ではありません

  • findViewById(int) は、ビュー階層を深さ優先で再帰的に反復します。 指定したViewから を返し、最初の View と一致する id .
  • コード指定がない限り id の前に割り当てられたXMLで定義された id を階層化します。 findViewById(R.id.somename) は常にXMLで定義されたViewを返しますので id 'd.

ビューを動的に作成し、割り当てる ID s

  • レイアウト XML で、空の ViewGroup と共に id .
  • などがあります。 LinearLayoutandroid:id="@+id/placeholder" .
  • プレースホルダーに入力するコードを使用します。 ViewGroupView s.
  • 必要な場合、または必要な場合は、任意の id は、各ビューに都合のよいものを選んでください。
  • これらの子ビューをplaceholder.findViewById(convenientInt)を使用して問い合わせます。

  • API17の導入 View.generateViewId() で、一意のIDを生成することができます。

自分の意見に言及し続けることを選択した場合 でインスタンス化する必要があります。 getApplicationContext() で各参照をNULLに設定してください。 onDestroy . どうやら リーク その Activity (破壊された後、それにしがみつく)のは、無駄なことです... :)

XMLを予約する android:id コードで使用するため

API17の導入 View.generateViewId() で、一意のIDを生成します。 (ご指摘いただいたtake-chances-make-changesさんに感謝します。)*。

もし、あなたの ViewGroup をXMLで定義できない(あるいは定義したくない)場合は、XMLでidを予約し、一意性を確保することができます。

これを 値/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 が裏側で衝突している。

レイアウト/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 は、どちらも 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);

*それほど悪くはない