android:id的范围是什么?

时间:2012-08-16 13:56:14

标签: android

  

可能重复:
  Scope of R.id values

有人可以澄清Android中资源ID的范围吗?最近我正在制作一个自定义标题栏,其中包含一个名为“header”的RelativeLayout。我在每个活动的 onCreate()处理程序中调用了这个标题栏:

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

我的一个活动在其布局中有一个ID为“header”的TextView,并且在Activity的 onCreate()中我做了

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

。 。 。它在运行时因ClassCastException而爆炸,显然是因为它认为我试图将RelativeLayout强制转换为TextView。在标题栏中更改RelativeLayout的名称会修复它。

但我真的不明白这一点。 Android资源ID是全局的吗?如果是这样的话,为什么不能在构建时捕获这个碰撞?

请注意,此问题之前已在SO:Scope of R.id values上提出过。 。 。 OP说“据我所知”,R.id是全球性的,但我的问题并不重复,因为我的问题都没有真正解决过。

3 个答案:

答案 0 :(得分:10)

  

Android资源ID是全局的吗?

它们在活动中是“全球性的”。标题栏位于活动中。布局在活动中。来自两者的小部件都将在活动中。两者中具有相同ID的小部件将出现在活动中,并代表findViewById()次呼叫的冲突点。

  

如果是这样的话,为什么不会在构建时捕获此碰撞?

首先,为什么会这样?构建系统如何知道您将采用res/layout/title_bar.xmlres/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(例如,ListView),因为它们的内容往往会有重复的ID(例如,每一行)在ListView中,从同一行布局资源中标记出来。)

答案 1 :(得分:3)

R. *值对于他们自己的类型是全局的。因此,您可以使用相同名称的R.stringR.id,但不能使用两个具有相同名称的ID。在你的情况下,我觉得做一个构建清洁也会解决你的问题。例如,看一下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的资源,或两个具有相同名称的drawable,或两个具有相同名称的字符串等,它将无法正常运行。

答案 2 :(得分:0)

R只是一个充满静态整数的java类。您的应用程序中只能有一个R.id.header值。 在您的布局中使用相同的ID是完全正确的,但如果您在一个布局中使用相同的ID,则可能会遇到您遇到的确切问题。 在你的情况下,findViewById首先找到你的RelativeLayout并返回它而不是TextView。这只是一个搜索视图的顺序问题。 例如,您可以通过在TextView的直接父级上调用findViewById来解决它。