4

I am creating ImageView in code:

ImageView vlogo = new ImageView(v.getContext());
        RelativeLayout.LayoutParams vlogoParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        vlogoParams.addRule(RelativeLayout.ALIGN_TOP,tv_visitor.getId());
        vlogoParams.addRule(RelativeLayout.ALIGN_LEFT, tv_visitor.getId());
        vlogoParams.addRule(RelativeLayout.ALIGN_BOTTOM, tv_visitor.getId());
        vlogo.setLayoutParams(vlogoParams);
        vlogo.setImageResource(R.drawable.star);
        rl.addView(vlogo);

The image is "scaled" by aligning it to TOP and BOTTOM of previously created tv_visitor view (that has been added to relative layout). But I asume that it isn't layedout yet(?). .requestLayout just before this code doesn't change a thing. Picture

By doing that I'm setting ImageView's height to the height of tv_visitor view. Which is OK. However the width seems to stay original.

And here comes the problem. The width stays not scaled. The way I do that is making .setAdjustViewBounds(true); not working. How should I proceed then?

As requested in comments I provide more info:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/news_scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff000000"
    android:scrollbars="none">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/fragment_news2">
    <View
        android:id="@+id/anchor_n"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffbb00"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true" />
</RelativeLayout>
</ScrollView>

The View is passed as an parameter and layout is gotten by:

RelativeLayout rl = (RelativeLayout) v.findViewById(R.id.fragment_news2);
Cœur
  • 37,241
  • 25
  • 195
  • 267
Bart Lizak
  • 85
  • 9
  • what's your `tv_visitor View` and what are its `LayoutParams` and are you sure the original image don't have any padding? – blizzard Feb 11 '15 at 21:21
  • It's created in Java as well. It's a TextView with MATCH_PARENT x WRAP_CONTENT. It's layed out on the right of an 0x0 "anchor" view. There are no paddings and margins for sure. I even tried to set them in Java (using px2dp formula) but it doesn't solve it as I got different results depending on the screens. – Bart Lizak Feb 11 '15 at 21:31
  • This is caused by a bug in `RelativeLayout`, in that it queries for the default measurement of it's children (bounded only by it's own size constraints) and then forces it's own modifications, without querying for the preferred dimensions given the constraints of the child. As a workaround, you could wrap it inside another container, which should at least allow the proper alignment (although the container's width would remain the same). Hardcoding the parent's height should also fix this. I'll add an answer later after exploring this a bit more. – corsair992 Feb 11 '15 at 21:55
  • 1
    Related question: [RelativeLayout not properly updating width of custom view](http://stackoverflow.com/questions/15398643/relativelayout-not-properly-updating-width-of-custom-view). Also see the open bug report on it: http://b.android.com/63673 – corsair992 Feb 11 '15 at 22:02

1 Answers1

2

The problem is due to the scaling of Imageview, since by default imageview is using ImageView.ScaleType.FIT_CENTER. As per the documentation FIT_CENTER performs the following operation:

Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. The result is centered inside dst.

Since the Image is resized and centered, you are seeing extra spaces on both left and right side. To avoid that set ScaleType to ImageView.ScaleType.FIT_END which in turn aligns the result to the right will solve the problem.

vlogo.setScaleType(ImageView.ScaleType.FIT_END);
blizzard
  • 5,275
  • 2
  • 34
  • 48
  • That worked for me. Thank you. However, it seems to stil have "invisible margin" to the left. The width stayed the same but the img moved to the right within it. It doesn't concern me and renders great on multiple screens. – Bart Lizak Feb 11 '15 at 22:19
  • 1
    @BartLizak Yes there will be invisible margin, since only the image is aligned right, the width of Imageview is not resized. To avoid that you need to resize the original Bitmap (`Bitmap.createScaledBitmap`) before assigning it to ImageView. – blizzard Feb 11 '15 at 22:38