Why is Android Studio designer displaying my custom view nested inside itself, while it isn't

564 Views Asked by At

I've got a custom view for my app named AvatarView:

<?xml version="1.0" encoding="utf-8"?>
<com.ulouder.views.AdvancedRelativeLayout android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_gravity="center_horizontal"
    android:layout_margin="0dp"
    android:padding="0dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CP"
        android:id="@+id/initialsView"
        android:layout_alignTop="@+id/avatarView"
        android:layout_alignLeft="@+id/avatarView"
        android:layout_alignBottom="@+id/avatarView"
        android:layout_alignRight="@+id/avatarView"
        android:background="@drawable/avatar_background"
        android:textColor="@color/white"
        android:gravity="center"
        android:textStyle="bold"
        android:textSize="8sp" />

    <com.makeramen.roundedimageview.RoundedImageView
        app:riv_corner_radius="20dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/avatarView"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginBottom="4dp"
        app:riv_border_color="@color/lightGray"
        app:riv_border_width="0.2dp" />

</com.uLouder.views.AdvancedRelativeLayout>

AdvancedRelativeLayout is just a superclass of RelativeLayout with a small fix, nothing special there. Then, I've created a view that uses my custom view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.ulouder.views.AvatarView
    android:layout_width="50dp"
    android:layout_height="50dp"/>

</LinearLayout>

Nothing fancy either. But in the designer view of the second layout XML, I'm getting this:

enter image description here

The editor displays my view hierarchy like it has a nested instance of itself, while clearly there isn't. If I delete either one, they both get deleted. If I declare attributes on one of them, other also gets it. They are clearly the same instance. The only exception is setting an ID. Then the problem disappears, and only single instance is displayed as expected.

I've rebuilt the project, restarted Android Studio, but it's still the same. What am I doing wrong?

UPDATE: Nope, now, after editing id, the problem still continues again.

UPDATE 2: It's not just a layout so I can't use <include> tag. It's a custom view which has custom logic inside.

UPDATE 3: Here is my custom view's (relevant) code:

public class AvatarView extends FrameLayout {
    public AvatarView(Context context) {
        super(context);
        init();
    }

    TextView initialsView;
    RoundedImageView imageView;


    public AvatarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    void init(){
        inflate(getContext(), R.layout.view_avatar, this);
        initialsView = (TextView) findViewById(R.id.innerInitialsView);
        imageView = (RoundedImageView) findViewById(R.id.innerImageView);
    }

    @SuppressWarnings("SuspiciousNameCombination")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec); //always square
        imageView.setCornerRadius(widthMeasureSpec / 2f);
        initialsView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, widthMeasureSpec * 30f);
    }

}

UPDATE 4: It appears that this happens wherever I put my custom AvatarView class, not just at one place.

1

There are 1 best solutions below

6
Rafael Berro On

I did not find any reason to inflate the same view inside your class constructor method after checking the custom views documentation. Try to remove the inflate inside your init method.

...

public AvatarView(Context context) {
    super(context);
    init();
}

...

public AvatarView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

void init(){
//  inflate(getContext(), R.layout.view_avatar, this);
    initialsView = (TextView) findViewById(R.id.innerInitialsView);
    imageView = (RoundedImageView) findViewById(R.id.innerImageView);
}

...