开发者

How can I use duplicate IDs in different layouts?

I have two different layouts for two different Activities. There is a button in each of these layouts with the same id: "@+id/btnOK". When I set a property for one of these buttons programmatically, I get a Nul开发者_开发技巧lPointerException. But when I change one of ids, everything is okay.

Is it really true that we cannot have duplicate IDs in different layouts in android?


On the "Duplicate Ids in layouts" topic, extracted from android developers

Defining IDs for view objects is important when creating a RelativeLayout. In a relative layout, sibling views can define their layout relative to another sibling view, which is referenced by the unique ID.

An ID need not be unique throughout the entire tree, but it should be unique within the part of the tree you are searching (which may often be the entire tree, so it's best to be completely unique when possible).

Which means different layouts may declare identical IDs, tho it's not a best practice.


I imagine there would be an issue in the R.java class, as this class will have public static members corresponding to each View id.

For it to work, the R.java class would need to rename some of those id's, and then how would you find them?


You can have the same IDs but it should be in different layouts. The same layout cannot handle duplicate IDs. I have taken two layouts as you did containing buttons having as "btn". I am calling the Activity2 having newxml.xml from the Activity1 having main.xml.

Here is my code:

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Next" />

</LinearLayout>

Activity1:

setContentView(R.layout.main);

Button button=(Button) findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent=new Intent(Activity1.this,Activity2.class);
            startActivity(intent);
        }
    });

newxml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Previous"/>

</LinearLayout>

Activity2:

setContentView(R.layout.newxml);

Button button=(Button) findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        finish();
    }
});


I resolved the problem but I did not find the reason. In my manifest file, one of activities had the "android:label="@string/app_name". I removed it and set it for my main activity.

Previous manifest:

<activity android:name=".ui.ActLogin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ui.ActTest" android:label="@string/app_name">
</activity>

New manifest:

<activity android:label="@string/app_name" android:name=".ui.ActLogin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ui.ActTest">
</activity>

Does anybody know the reason?


To me it looks all right (and sometimes quite natural) to use duplicate ids, as long as you do it correctly: instead of Activity.findViewById() which always returns the first matching view, use ViewGroup.findViewById() (ViewGroup can be LinearLayout, FrameLayout etc) which returns view withing the view group.

To avoid lint warnings:

  1. (Preferred) Place content of the ViewGroup in separate layout XML and use

      <include layout="@layout/myLayout" android:id="@+id/specificId" />
    

    This way you can have several includes of same layout with different parent ids (but same child ids) and lint will never complain.

  2. Disable Lint warning for the project by unticking the box "Duplicate ids within a single layout" in *Settings/Editor/Inspections*

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜