Kitesurfer
Kitesurfer

Reputation: 3561

Override of Resources in library project

im having a library project which has a Default Fragment implementation. I also added some template methods where the Main Project can hook in and return another Layout Resource ID to be inflated. The Problem i get is that the Runtime sees duplicated IDs. I wonder how this can be avoided ?

@IdRes
@Override
public int getDrawerLayoutResID() {
    return R.id.drawerLayout;
}

@LayoutRes
@Override
public int getLayoutResID() {
    return R.layout.master_detail;
}

Lib Project:

 BaseFragment
 layout.xml

Main Project:

 ConcreteFragment
 layout.xml

I only know this problem from nested Fragments. But im not using any nested Fragments. I checked the generated R files, both contain the same ID for the same IDs (layout and drawer).

AFAIK the resource merger should override resources which having the same name like an layout.xml in the library project.

All i want is some type of customization for the main Project, as most code is backed in the library project. To archive this customization i have an layout file which is part of the Activiy layout:

Library Project file:

<!-- The navigation drawer -->
<fragment
    android:name="com.examle.core.ui.fragment.NavigationDrawerFragment"
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    tools:layout="@layout/fragment_navigation" />

Concrete Project file:

<!-- The navigation drawer -->
<fragment
    android:name="com.examle.ui.fragment.ConcreteFragment"
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    tools:layout="@layout/fragment_navigation" />

The Runtime fails when i invoke setContentView in the Activity with expection:

Stacktrace:

 Caused by: java.lang.IllegalArgumentException: Binary XML file line #45: Duplicate id 0x7f08006d, tag null, or parent id 0x7f08006b with another fragment for com.example.android.fragment.ConcreteFragment
        at android.app.Activity.onCreateView(Activity.java:4751)

Upvotes: 1

Views: 1933

Answers (1)

Mike Laren
Mike Laren

Reputation: 8178

According to the docs, when the Android Gradle plugin merges two manifest files that declare the same element then it checks their configuration (i.e. their XML tags and attributes) to check whether that they are identical in the two manifests. If they are then gradle keeps only one of them, if they're not then gradle detects a conflict and adds both elements to the manifest.

Since your two fragments are substantially different, gradle is adding both of them to the final app. Then at runtime, android complains that it found two fragments with the same android:id and throws the error that you saw.

To fix this problem you should remove one of the fragment declarations or alternatively make them the same for both app and library.

Upvotes: 1

Related Questions