6

重複の可能性:
R.id値の範囲

誰かがAndroidのリソースIDの範囲を明確にしてくれませんか?最近、「ヘッダー」と呼ばれるRelativeLayoutを含むカスタムタイトルバーを作成していました。したがって、各アクティビティのonCreate()ハンドラーでこのタイトルバーを呼び出していました。

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_layout);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);  

私のアクティビティの1つは、レイアウトに「header」のIDを持つTextViewがあり、そのアクティビティのonCreate()

TextView tv1 = (TextView)findViewById(R.id.header); 

。。。これは、実行時にClassCastExceptionで爆発しました。これは、RelativeLayoutをTextViewにキャストしようとしていると考えたためと思われます。タイトルバーのRelativeLayoutの名前を変更すると、修正されました。

しかし、私はこれを本当に理解していません。AndroidリソースIDはグローバルですか?もしそうなら、なぜこの衝突はビルド時にキャッチされないのでしょうか?

この質問は以前にSO:R.id値の範囲で尋ねられたことに注意してください 。。。OPが「私が知る限り」と言った場合、R.idはグローバルですが、私の質問はどちらも実際にはその質問に対応していないため、重複していません。

4

3 に答える 3

10

AndroidリソースIDはグローバルですか?

それらはアクティビティ内で「グローバル」です。タイトルバーがアクティビティにあります。レイアウトはアクティビティにあります。両方のウィジェットがアクティビティに含まれます。両方のIDが同じウィジェットがアクティビティに含まれ、呼び出しの競合ポイントを表しfindViewById()ます。

もしそうなら、なぜこの衝突はビルド時にキャッチされないのでしょうか?

まず、なぜそうなるのでしょうか。ビルドシステムは、あなたが両方を同じアクティビティで使用することres/layout/title_bar.xmlをどのように認識しているのでしょうか?res/layout/whatever_the_heck_you_called_it.xml

第二に、IDが重複していても問題はありません。開発者としてのあなたの仕事は、あなたにユニークな結果をもたらすものは何でも呼び出すfindViewById()ことです。たとえば、次のようにすることができます。

TextView tv1 = (TextView)(findViewById(android.R.id.content).findViewById(R.id.header));

重複したIDを保持しました。保守性のために、ここでは、個別のIDを使用して、行ったルートを選択することをお勧めします。ただし、コンテンツのIDが重複する傾向があるため(たとえば、の各行が同じ行レイアウトからスタンプアウトされるため)、AdapterViewこれまでに実装したすべてのID(たとえば、)など、意図的に重複したIDを使用する場合が多くあります。資源)。ListViewListView

于 2012-08-16T14:02:10.027 に答える
3

R. *値は、独自のタイプに対してグローバルです。したがって、R.stringR.idを同じ名前にすることはできますが、同じ名前のIDを2つ持つことはできません。あなたの場合、ビルドクリーンを実行することで問題も解決したと思います。たとえば、R.javaファイルの内容を見てみましょう。

    public static final class drawable {
    public static final int icon=0x7f020000;
    public static final int info=0x7f020001;
    public static final int menu=0x7f020002;
    public static final int splash1=0x7f020003;
}
public static final class id {
    public static final int ImageView02=0x7f070008;
    public static final int bestTimeTextView=0x7f070005;
    public static final int infoButton=0x7f070003;
    public static final int infoImageView=0x7f070000;
    public static final int levelSpinner=0x7f070002;
    public static final int menuImageView=0x7f070001;
    public static final int selectLevelTextView=0x7f070004;
    public static final int startButton=0x7f070006;
    public static final int timeTextView=0x7f070007;
}
public static final class layout {
    public static final int info=0x7f030000;
    public static final int menu=0x7f030001;
    public static final int splash=0x7f030002;
}
public static final class raw {
    public static final int down=0x7f040000;
    public static final int up=0x7f040001;
}
public static final class string {
    public static final int appname=0x7f060000;
    public static final int besttime=0x7f060002;
    public static final int help=0x7f060004;
    public static final int selectlevel=0x7f060001;
    public static final int start=0x7f060003;
}

ここでは、描画可能部分とレイアウト部分の両方で使用される情報名があり、アプリは完全に機能します。ただし、同じIDの2つのリソース、同じ名前の2つのドローアブル、または同じ名前の2つの文字列などを追加しようとすると、正しく機能しません。

于 2012-08-16T14:00:53.753 に答える
0

Rは、静的整数でいっぱいのJavaクラスです。アプリケーションで使用できるR.id.headerの値は1つだけです。レイアウトで同じIDを使用することはまったく問題ありませんが、1つのレイアウトで同じIDを使用すると、発生した問題とまったく同じ問題が発生する可能性があります。あなたの場合、findViewByIdは最初にRelativeLayoutを見つけ、TextViewの代わりにそれを返しました。ビューを検索する順序の問題です。たとえば、TextViewの直接の親でfindViewByIdを呼び出すことで、それを回避することができます。

于 2012-08-16T14:00:57.613 に答える