layout_height should be a function of layout_width - android

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.

Related

Expandable layout - can't with change layout params

I have problem with changing Exapandable layout params. I'm using layout from this library:
https://github.com/AAkira/ExpandableLayout
I put ImageView inside this layout and than when I download picture into ImageView I want my layout to wrap this image.
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
android:id="#+id/expandable_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#+id/event_accepted_people_scrollview"
android:layout_alignParentStart="true">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/card_map_icon"
android:layout_width="70dp"
android:layout_height="70dp"
app:srcCompat="#drawable/vector_drawable_ic_map_black___px"
android:tint="#color/skilltrade_grey"
android:scaleType="center"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:background="#drawable/ripple_effect"/>
<TextView
android:id="#+id/no_map_snapshot_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/no_map_snapshot"
android:gravity="center_horizontal"
android:layout_marginBottom="15dp"
android:layout_below="#id/card_map_icon"/>
<ImageView
android:id="#+id/carditem_map_snapshot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/details_map_textview"
android:scaleType="center"
android:layout_marginTop="5dp" />
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
Problem is that layout wraps only AppCompatImageView and TextView because ImageView source is not set and it's height is 0. After downloading picture layout is not wraping content correctlly...
That's what I'm doing now:
-I download picture in size 640x480.
-Than I scale it to match my screen
-After that when I know height of my image I change params of my Expandable layout like this:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mapSnapshot.getLayoutParams();
params.width = width;//scaled picture width
params.height = height;//scaled picture height
mapSnapshot.setLayoutParams(params);
expandableArea.updateViewLayout(mapSnapshot, params);
Unfortunately it's not working and layouts height is still not matching ImageView...
I would be grateful for any help :)

Keep aspect ratio of view when using layout_weight property

I have a LinearLayout with an ImageView inside. The ImageView is using layout_weight to take up half of the width of the LinearLayout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<ImageView
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1" />
</LinearLayout>
Now, what I want to do is make sure this ImageView is already a square. I can't simply set the height because the width is dynamic, depending on the width of the current screen. Is there a way I can make sure the height always matching the width of the view?
I've tried this:
imageView.getLayoutParams().height = imageView.getLayoutParams().width;
imageView.requestLayout();
But I get a NPE. Any ideas?

ImageView adjustViewBounds not working with Relative Layout

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

set remaining height to view at runtime

I am writing an application where need to assign rest of screen space to view.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/txtView_1"
android:layout_width="match_parent"
android:layout_height="100dp" />
<TextView
android:id="#+id/txtView_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Test Text" />
</LinearLayout>
and to set runtime I am using following:
private void process() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int txtView1Height = txtView_1.getHeight();
LayoutParams layoutParams = (LayoutParams) txtView_2.getLayoutParams();
layoutParams = new LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
(metrics.heightPixels - txtView1Height));
txtView_2.setLayoutParams(layoutParams);
}
But here it's taking not exact same remaining height..since textview sting not placing in center(this is how I simply check)...it might be mistaken to set height in pixel.
Any suggestion here?
You can use weight xml parameter
<TextView
android:id="#+id/txtView_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:text="Test Text" />
or in your case simple set height to match_parent
android:layout_height=match_parent
To check even more simpler set gravity to bottom. If you still want to do this programmatically dont use DisplayMetrics to get height (Action Bar and Software Buttons are also a part of display) use your root LinearLayout height. Also check if txtView1Height is not 0 (maybe view was not drawed at the moment of calculation)

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.

Categories

Resources