3

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.

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
  • Definitely odd. Is it possible there's something in your Activity class that's programatically adding a view, in addition to the one in the layout xml file? – Joshua Carmody Jun 03 '16 at 02:19
  • @JoshuaCarmody that was exactly what I thought too. There is only one place that I'm inflating a single xml, and it's on the initialization code that's just called from the constructor (obviously, once) and nowhere else. and that first XML is the one I've posted in my question. – Can Poyrazoğlu Jun 03 '16 at 02:27
  • Have you tried the same with any other `CustomView` in a different file? – Akash Agarwal Jun 03 '16 at 02:55
  • @AkashAggarwal yes, it happens again too. – Can Poyrazoğlu Jun 03 '16 at 06:31
  • You could try specifying an ID for each view or test the same files on another machine. Maybe the problem is with android studio. – Akash Agarwal Jun 03 '16 at 13:24

1 Answers1

0

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);
}

...
Rafael Berro
  • 2,518
  • 1
  • 17
  • 24
  • It's *not* just a layout. It's a custom view with custom logic. – Can Poyrazoğlu Jun 03 '16 at 02:12
  • can you share your custom view class here? – Rafael Berro Jun 03 '16 at 02:28
  • why are you inflating the view again inside the init method? – Rafael Berro Jun 03 '16 at 02:43
  • How do you think that my view code, which just a class file, will automagically inflate the appropriate XML and add it as its own child then? – Can Poyrazoğlu Jun 03 '16 at 06:31
  • If you are still inflating the layout, it will be always two views. Because you're inflating a custom view (AdvancedRelativeLayout) inside another one (AvatarView). Did you try to build it dynamically? – Rafael Berro Jun 03 '16 at 16:59
  • I know that there would be two layouts, but both of them are displayed as AvatarView, while one is AvatarView and one is AdvancedRelativeLayout. and, when I set an attribute on on one of them, the other also gets set. there is clearly a problem here other than inflating a view.. – Can Poyrazoğlu Jun 04 '16 at 09:22