1

I have a layer-list within a file layers.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/outer_rect">
    <shape android:shape="rectangle">
        <stroke
                android:width="3dp"
                android:color="@color/gray4"/>
        <solid android:color="@color/white"/>
    </shape>
</item>
<item android:top="10dp" android:bottom="10dp" android:left="10dp" android:right="10dp"
      android:drawable="@drawable/dot_pattern_bitmap"/>
</layer-list>

This is used in a customized FrameLayout customView.xml:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/layers"/>
</merge>

which itself is used e.g. in

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/space_m"
    android:orientation="vertical">

<my.namespace.customView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</FrameLayout>

Additionally, I have the CustomView.java class to edit the behavior of the customView (and especially the layers).

In there, I am trying to achieve an update of the size of the layer-list depending on the size of the customView (and a parameter 'ratio'). I tried it like this:

// ...
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    layoutWidth = MeasureSpec.getSize(widthMeasureSpec);
    layoutHeight = MeasureSpec.getSize(heightMeasureSpec);

    readjustSize(ratio);
}

private void readjustSize(final double ratio) {
    if (layoutHeight != 0 && layoutWidth != 0) {
        // determine desired width and height using the layout width
        int desiredWidth = layoutWidth;
        int desiredHeight = (int) (layoutWidth / ratio);

        // if it does not fit, adjust using the layout height
        if (desiredHeight > layoutHeight) {
            desiredHeight = layoutHeight;
            desiredWidth = (int) (layoutHeight * ratio);
        }

        // get the basic layer
        final LayerDrawable ld =
            (LayerDrawable) ContextCompat.getDrawable(getContext(), R.layers);
        final GradientDrawable outerRectShape =
            (GradientDrawable) ld.findDrawableByLayerId(R.id.outer_rect);

        // and adapt the size
        outerRectShape.setSize(desiredWidth, desiredHeight);
        outerRectShape.setBounds(0, 0, desiredWidth, desiredHeight);

        // redraw
        invalidate();
        requestLayout();
    }
}

So, that was lots of code... Unfortunately, this does not work properly. If the frame layout is loaded the first time, I can only see a very small rectangle.

Only if I switch back and forth to this view, the size is applied as I wanted to:

Does anybody have ideas?

Caro
  • 35
  • 2
  • 7
  • set ImageView to match_parent in width. – D.J Oct 18 '16 at 09:35
  • The ImageView itself does have match_parent in width. The containing view does not, but I already tried match_parent for both width and height, for width only or for none (as posted). This does not make any change. – Caro Oct 18 '16 at 09:41
  • In FrameLayout it is wrap_content. – D.J Oct 18 '16 at 09:42
  • Yes, as I meant by my previous answer: I already changed this to all possible variations of match_parent and wrap_content. This does not solve the problem. – Caro Oct 18 '16 at 09:45

1 Answers1

0

Finally, I found the answer myself. :) Actually, it was quite simple. When I was getting hold of the layer drawable by

final LayerDrawable ld =
    (LayerDrawable) ContextCompat.getDrawable(getContext(), R.layers);

I was only getting the resource in general, not my concrete src for the image drawable. When I adapted the code to

final View root = inflate(getContext(), R.layout.custom_view, this);
final ImageView imageView = (ImageView) root.findViewById(R.id.layers);
final LayerDrawable ld = (LayerDrawable) imageView.getDrawable();

in the CustomView initialization and giving the ImageView the id "layers", it worked as expected.

Additionally, I had to change the order of calling methods in onMeasure:

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    layoutWidth = MeasureSpec.getSize(widthMeasureSpec);
    layoutHeight = MeasureSpec.getSize(heightMeasureSpec);

    readjustSize(ratio);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} 

EDIT: This only works for Android versions >= 6.0. For older versions, I still have the same problem as described in the question.

Caro
  • 35
  • 2
  • 7