ImageView adjustViewBounds not working with Relative Layout - android

I have an ImageView and have set its layout_height to "100dp" and its layout_width to "wrap_content".
The drawable used has bigger actual dimensions that are 130dp (width) X 215dp (height).
When the ImageView is placed inside a LinearLayout, if I set adjustViewBounds to true, it gets a width that is measured according to the drawable's aspect ratio and the layout_width.
However, when placed inside a RelativeLayout the ImageView gets the same width as the drawable (130dp), no matter the adjustViewBounds settings.
In both cases the image renders correclty without distortion, however the ImageView's bounds are different.
The RelativeLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/background_light">
<ImageView
android:layout_width="wrap_content"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:src="#drawable/phone_orange"
android:contentDescription="#null" />
</RelativeLayout>
The LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/background_light"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:contentDescription="#null"
android:src="#drawable/phone_orange" />
</LinearLayout>
Why does the ImageView measures differently in these 2 scenarios? Is there a way to make the ImageView behave always like being in the LinearLayout case (wrapping it with a LinearLayout works but it's not a clean solution)?

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:adjustViewBounds="true"
I got it there

use width and height of imageview to match_parent
private void addView(Drawable d) {
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
ImageView iv = new ImageView(this);
iv.setImageDrawable(d);
iv.setAdjustViewBounds(true);
iv.setScaleType(ImageView.ScaleType.MATRIX);
iv.setLayoutParams(lparams);
rl.addView(iv);
iv.setOnTouchListener(this);
}

Related

match_parent in parent with minWidth results in zero width child

When I have a FrameLayout that uses a minWidth and then I place an ImageView into it with match_parent, the resulting width is 0.
See this layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout // is width 100 from minWidth
android:id="#+id/parent"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:minWidth="100dp"
android:padding="10dp"
android:background="#FF0000">
<ImageView // should be width 80, but is 0. Why?
android:id="#+id/child"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:background="#FFFF00"/>
</FrameLayout>
</FrameLayout>
I would expect the view to look like this:
But what I get is an ImageView with a 0 width:
Any idea what is going on and how I can have child take up the whole width of parent in this case?
Edit:
Adding an image to the ImageView does not fix the issue, it just sets the child width to the image size.
You have to set android:adjustViewBounds="true" in your ImageView
<ImageView
android:scaleType="fitCenter"
android:adjustViewBounds="true"
tools:srcCompat="#drawable/...."
Please note that adjustViewBounds will not increase the size of the ImageView beyond the natural dimensions of the drawable.

Putting ImageView on the bottom of the screen

I am trying to put the ImageView on the bottom of the layout with following XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#EEEEEE"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:src="#drawable/photo" />
</LinearLayout>
</LinearLayout>
I am following the instructions found here http://sandipchitale.blogspot.co.uk/2010/05/linearlayout-gravity-and-layoutgravity.html
Only difference is that I use ImageView instead of Button as here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/Button03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="bottom" >
</Button>
</LinearLayout>
</LinearLayout>
Which puts the button on the expected place:
Unfortunately this isn't the case in my XML on the top of the post. The ImageView isn't placed on the bottom as the Button in reference XML is.
Any ideas why that happens ?
You should change a setting in ImageView itself, to be precise set android:scaleType="fitEnd" on your ImageView.
The other answers seem to be workarounds, including your own answer. This is not a problem with a layout, but with where inside the ImageView the image is loaded when the dimensions of the image and the screen aren't similar, (i.e. the width/height ratio is very different). By default it would load the image in the middle of the ImageView.
Try using RelativeLayout instead of LinearLayout and use parameter android:layout_alignParentBottom = "true".
EDIT: Try giving layout_height and layout_width as wrap_content for your LinearLayout that holds your ImageView.
Or it might be that the image you are using has extra space above and below it.
UPDATE:
The problem is with the size of the image. It is much larger than the screen size. I would suggest you to programmatically read the screen size of the device with below code:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
and set the height and width for imageView programmatically as below:
image_view.getLayoutParams().height = height - 50;
image_view.getLayoutParams().width = width - 50;
Try this inside relative layout
<ImageView
android:id="#+id/imageView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:adjustViewBounds="?attr/isLightTheme"
app:srcCompat="#drawable/client_app_footer" />
tested & working as expected
you did not include android:layout_gravity="bottom" line in your imageview.
I have resized photo size from width 2560 to width 270 and finally ImageView went to bottom.

layout_height should be a function of layout_width

Assuming portrait mode, I have an ImageView who's image will be of variable size (yet always square). I would like the ImageView's width to always be equal to the layout's width (fill_parent) and as you can see the scaleType is "centerCrop" which will scale.
The problem is that if I set the *layout_height* also to "fill_parent" then, being that centerCrop retains the original aspect ratio, the height takes precedence and the image is cropped on the left and right. (this of course assumes a screen that is taller than it is wide). However, if I set the layout_height to "wrap_content", then the height is no longer scaled and I end up with a cropped rectangle. It does this because it respects the original height of the image.
Is there a layout_height setting that will give precedence to a layout_width of "fill_parent"?
<ImageView
android:id="#+id/iv_image"
android:layout_width="fill_parent"
android:layout_height="?"
android:layout_below="#id/header"
android:layout_centerHorizontal="true"
android:contentDescription="#string/cd_image"
android:padding="0dp"
android:scaleType="centerCrop"
android:src="#drawable/blank_album" />
Removing the android:layout_height attribute causes a crash:
java.lang.RuntimeException: Binary XML file line #16: You must supply a layout_height attribute.
Setting android:layout_height="0dp" crushes the image vertically.
Answer: Using a combination of responses from other users, I was able to find a simple solution that works well for me.
First, the image view has this configuration (note the fitStart):
<ImageView
android:id="#+id/iv_album"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#id/header"
android:layout_gravity="top"
android:background="#FF00FF00"
android:contentDescription="#string/app_name"
android:padding="0dp"
android:scaleType="fitStart"
android:src="#drawable/blank_album" />
Then programmatically, a small modification to the height of the image to match the width (within Activity.onResume())
ImageView iv = (ImageView)findViewById(R.id.iv_album);
boolean bPost = iv.post(
new Runnable()
{
public void run()
{
ImageView iv = (ImageView)findViewById(R.id.iv_album);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)iv.getLayoutParams();
params.width = ASong.this.findViewById(R.id.song_view_layout_top).getWidth();
params.height = params.width;
iv.setLayoutParams(params);
}
});
if (bPost == false)
{
throw new RuntimeException("runnable not posted");
}
I had to deal with this issue yesterday. This is the XML that solved my problem:
<ImageView
android:id="#+id/character"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
android:src="#drawable/ma_un1_001" />
see thread here: Center drawable and scale height
To cut a long story short:
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
Alternatively, you can do it programmatically:
Surround the ImageView with a LinearLayout
<LinearLayout
android:id="#+id/container"
android:layout_below="#id/header"
android:layout_centerHorizontal="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/iv_image"
android:layout_width="fill_parent"
android:layout_height="?"
android:contentDescription="#string/cd_image"
android:padding="0dp"
android:scaleType="centerCrop"
android:src="#drawable/blank_album" />
</LinearLayout>
Then, in your onCreate(), insert
findViewById(R.id.container).post(
new Runnable() {
public void run() {
LinearLayout container = (LinearLayout)findViewById(R.id.container);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)container.getLayoutParams();
params.height = params.width;
container.setLayoutParams(params);
}}
);
The code must be into post() because the main process can't directly modify the layout structure.

ImageView increases and decreases dynamically after the size of a textfield

I have a layout like this one:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#272727"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/BtnSlide"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#null"
android:src="#drawable/lin" />
<TextView
android:id="#+id/textView1"
android:layout_width="275dp"
android:layout_height="50dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="100dp"
android:text="HEADER"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="2.2dp"
android:src="#drawable/logo" />
The ImageView is placed to the right of the screen. But I'm facing an issue, the ImageView increases and decreases in height and width depending on the length of the TextView, how can I make this work properly, without the ImageView changing size?
The problem here is that your ImageView matches the size of your parent, that is your LinearLayout (with id tabBar).
That LinearLayout wraps the content on his height, so, it sums all "heights" of his contents. The LinearLayout will take the height of TextView + the height of the ImageButton. Then, the ImageView will match that height.
A solution depends on what you are trying to do, but you can try to:
Set a predefined height in your ImageView
Use a RelativeLayout instead of a LinearLayout and align all your views depending on each other
My suggestion is to set layout_weight to all the components so that their size is fixed regardless of their contents:) See here for more details

Android: widget align question

in a RelativeLayout I have an Imageview that serves as the background of the widget and a RelativeLayout. The RelativeLayout is "on" the Imageview, but i want it to be in the center of the Imageview. How can i align it to it?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="470px"
android:layout_height="120px"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:id="#+id/widgetlayout"
>
<ImageView android:id="#+id/ImageView00"
android:layout_width="470px"
android:layout_height="120px"
android:scaleType="fitXY"
android:background="#android:color/transparent"
>
</ImageView>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="470px"
android:layout_height="120px"
android:layout_gravity="center"
android:gravity="center_horizontal|center_vertical"
android:id="#+id/widgetlayoutbelso"
>
...
Any ideas?
Thanks
Set android:layout_centerInParent to true on your inner relative layout (you can probably remove the gravity flags too at this point).
Your ImageView and RelativeLayouts have exactly the same layout sizes (width and height), so the RelativeLayout can't really be centered in the ImageView. You could try setting the RelativeLayout layout sizes to wrap_content, and set android:layout_centerInParent="true" (as David said).

Categories

Resources