5

I have created a custom view (compound view) that is inherited from FrameLayout and contains several child views in it:

MediaComponentView.java:

final public class MediaComponentView extends FrameLayout {
    private int ratio = 1;

    private ImageView imageView;
    private CircularProgressView progressView;
    private View downloadButton;
    private View cancelButton;
    private View playButton;

    public MediaComponentView(Context context) {
        super(context);
        initializeViews();
    }

    public MediaComponentView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initializeViews();
    }

    public MediaComponentView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initializeViews();
    }

    private void initializeViews() {
        inflate(getContext(), R.layout.view_media_component, this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        imageView = (ImageView) this.findViewById(R.id.image_view);
        progressView = (CircularProgressView) this.findViewById(R.id.progress_view);
        downloadButton = this.findViewById(R.id.download_button);
        cancelButton = this.findViewById(R.id.cancel_button);
        playButton = this.findViewById(R.id.play_button);
    }

    public void setRatio(int ratio) {
        this.ratio = ratio;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth() / ratio);
    }

}

view_media_component.xml:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <com.makeramen.roundedimageview.RoundedImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        app:riv_border_color="#eee"
        app:riv_border_width="1px"
        app:riv_corner_radius="3dp"
        />

    <com.github.rahatarmanahmed.cpv.CircularProgressView
        android:id="@+id/progress_view"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/download_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/icon_chat_media_download"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/cancel_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@android:drawable/ic_menu_close_clear_cancel"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/icon_chat_media_play"
        android:visibility="gone"
        />
</merge>

Usage of the compound view:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:layout_marginTop="4dp"
    android:layout_marginLeft="2dp"
    android:layout_marginRight="2dp"
    >

    <some.hidden.package.MediaComponentView
        android:id="@+id/media_0"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="2dp"
        android:background="#00ff00"
        />

    <some.hidden.package.MediaComponentView
        android:id="@+id/media_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="2dp"
        android:background="#ff0000"
        />
</LinearLayout>

The issue is that the "image_view" is not layouted correctly. It does not match parent.

I have checked that the MediaComponentView itself has correct size by setting background to it. It HAS correct size.

But the child view has incorrect size. I guess it happens because of the overriden onMeasure() method in the MediaComponentView.

Any help or explanation would be appreciated.

Ermat Alymbaev
  • 721
  • 6
  • 15

1 Answers1

5

You need to call measureChildren(int widthMeasureSpec, int heightMeasureSpec) at the end of your onMeasure() override. The child views don't know that you changed the height.

Reuben Scratton
  • 38,595
  • 9
  • 77
  • 86
  • Unfortunately this does not solve the issue. Child views have changed the way they are placed, but their size is still incorrect. – Ermat Alymbaev Nov 04 '15 at 09:50
  • It'll work. What are you using for the height measurespec? It should be MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, getMeasuredWidth() / ratio). – Reuben Scratton Nov 04 '15 at 11:04
  • The following code solved the issue: measureChildren(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getMeasuredWidth() / ratio, MeasureSpec.EXACTLY)); – Ermat Alymbaev Nov 04 '15 at 11:50
  • thank you very much! One last question - what about performance of the code above? Won't it make layout drawings slower? – Ermat Alymbaev Nov 04 '15 at 11:52
  • Glad you got there in the end. There will be a small performance hit coming from measuring all the child views twice. If you want to avoid this, then *don't* call measureChildren() a 2nd time, instead just modify the height measurespec you pass to super.onMeasure(), i.e. make it EXACTLY a ratio of the width measurespec. – Reuben Scratton Nov 04 '15 at 12:01
  • it would be great if you could modify your original answer and provide the code completely (for best performance). I think it would be helpful for others as well. – Ermat Alymbaev Nov 08 '15 at 09:07