Android layout_height to wrap smallest child - android

As part of a larger project, I'm attempting to create a custom image gallery which will hold images from the web. I have no control over their size and their layout (order, total number [up to ten], and number per row [up to three]) is defined by the API I'm working with. I'm using nested LinearLayouts to build the loose grid programmatically but this is an XML proof of concept...
<?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="wrap_content"
android:orientation="vertical"
android:divider="#drawable/photoset_vert_divider"
android:showDividers="middle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:divider="#drawable/photoset_horz_divider"
android:showDividers="middle">
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:src="#drawable/tall" />
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:src="#drawable/tall" />
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:src="#drawable/wide" />
</LinearLayout>
</LinearLayout>
This is 60% of what I'm looking for and gets me
…but this is my target:
What I want is a android:layout_height="wrap_smallest_content" sort of thing that scales all the ImageViews to the correct size and then crops them all down to match the "shortest" child.

Since you say you're going to eventually do this programmatically, you could always just subclass LinearLayout to find the smallest height of the containing ImageViews as they load and then set that as the layout's height. Then all you'd have to do with the images is set their height to match_parent.

It's really better to set the fixed layout_height to inner LinearLayout. You can just do this in XML
If you're focusing on variety of devices then give a id to the inner LinearLayout then set the LinearLayout size dynamically by measuring the screen size of the device. To measure the screen size programmatically
By using the DisplayMetrics you can get height and width of the screen of any device.
here is the code.
DisplayMetrics metrics;
int width = 0, height = 0;
In your onCreate Method
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
xheight = metrics.heightPixels;
xwidth = metrics.widthPixels;
Try this to get the Screen height.
Then set the inner LinearLayout programmatically like this
linearLayout.getLayoutParams().height = xheight - 50;
Depending upon the xheight change the - 50 value
the your xml will change to something like this
<?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="wrap_content"
android:orientation="vertical"
android:divider="#drawable/photoset_vert_divider"
android:showDividers="middle">
<LinearLayout
android:id="#"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:divider="#drawable/photoset_horz_divider"
android:showDividers="middle">
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="match_parent"
android:src="#drawable/tall" />
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="match_parent"
android:src="#drawable/tall" />
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:layout_height="match_parent"
android:src="#drawable/wide" />
</LinearLayout>
</LinearLayout>

Related

minHeight not working with weight=“1” in Linearlayout

I want a View that can have a minimum height or wrap_content if screen size is small and if screen size is large then occupy the rest of the space. This view is middle child of its parent.
Currently, I am using weight with LinearLayout. It's working fine with large screen but on a small screen its not showing the view.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/speaker_detail_background"
android:clickable="true"
android:paddingLeft="#dimen/padding_7dp"
android:paddingRight="#dimen/padding_7dp"
android:orientation="vertical"
>
<ImageView
android:id="#+id/down_arrow_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:padding="#dimen/padding_15dp"
android:src="#drawable/down_arrow_icon" />
<RelativeLayout
android:id="#+id/lytSpeakerDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/down_arrow_image_view"
android:minHeight="200dp"
android:layout_weight="1"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<RelativeLayout
android:id="#+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:visibility="visible"
>
<com.harman.jblconnectplus.ui.customviews.CustomFontTextView
android:id="#+id/speaker_name_title_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#android:color/transparent"
android:drawableLeft="#drawable/edit_name"
android:drawablePadding="#dimen/padding_5dp"
android:ellipsize="end"
android:maxLength="16"
android:text="#string/speaker_name"
android:textColor="#android:color/white"
android:textSize="#dimen/textSize_18sp"
app:font="#string/font_name_opensans_semi"
/>
<com.harman.jblconnectplus.ui.customviews.CustomFontTextView
android:id="#+id/setting_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/speaker_name_title_textview"
android:layout_centerHorizontal="true"
android:text="#string/setting"
android:visibility="invisible"
android:textColor="#color/white"
android:textSize="14sp"
app:font="#string/font_name_opensans_semi"
/>
</RelativeLayout>
<LinearLayout
android:id="#+id/lytSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#id/title_bar"
android:layout_marginLeft="#dimen/brightness_margin"
android:layout_marginRight="#dimen/brightness_margin"
android:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/darker"
android:layout_gravity="center_vertical"
/>
<SeekBar
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/seekBar"
android:thumb="#drawable/knob"
android:progressDrawable="#drawable/seekbar_progressbar"
android:indeterminate="false"
android:splitTrack="false"
android:maxHeight="3dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:progress="0"
android:secondaryProgress="0"
android:max="255"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/brighter"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:id="#+id/bottom_details_layout"
android:layout_height="wrap_content"
android:background="#drawable/round_border_white_bg"
android:orientation="vertical"
android:layout_marginTop="#dimen/margin_20dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/padding_5dp"
android:gravity="bottom">
<include layout="#layout/speaker_detail_firmware_layout" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#color/divider_view" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/speaker_detail_voice_layout" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Please suggest.
Your View is being constrained. minHeight is not guaranteed to be honored if the View is constrained. See the documentation.
android:minHeight
Defines the minimum height of the view. It is not guaranteed the view will be able to achieve this minimum height (for example, if its parent layout constrains it with less available height).
Maybe a ScrollView is something that you can use since it gives you virtually unlimited space. The question is what you want to happen when space becomes an issue and everything just can't fit.
i had solve this problem. set weight "1" of layout in XML File(in my
case XML is same as Given above), it will work in case of if Screen
size is large and also check grammatically if size of view is less
than a minimum size then set height of view grammatically. sample
code:-
Set ViewTreeObserver to View:-
lytSpeakerDetails = (RelativeLayout) view.findViewById(R.id.lytSpeakerDetails);
ViewTreeObserver viewTreeObserver = lytSpeakerDetails.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener);
and in Listener's callback check if layout height is less than minimum then set height to minimum:-
ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (!isAdded())
return;
lytSpeakerDetails.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height = lytSpeakerDetails.getMeasuredHeight();
LinearLayout.LayoutParams imgViewParams = (LinearLayout.LayoutParams) lytSpeakerDetails.getLayoutParams();
/* imgViewParams.setMargins(0, (int) ( x * 1.5f) + (int) getResources().getDimension(R.dimen.card_shadow_y), 0, (int) x );
lytSpeakerDetails.setLayoutParams(imgViewParams);*/
if(height < (int)getResources().getDimension(R.dimen.brightness_minimum_height)) {
LinearLayout.LayoutParams rel_btn = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, (int) getResources().getDimension(R.dimen.brightness_minimum_height));
lytSpeakerDetails.setLayoutParams(rel_btn);
}
}
};

make minimum height based on imageview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:minHeight="400dp"
android:background="#android:color/black"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/invitation_imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="1dp"
android:scaleType="centerCrop"
/>
<ImageView
android:id="#+id/invitation_avatar_view_1"
android:layout_width="28dp"
android:layout_height="28dp"
android:scaleType="centerCrop"
android:layout_margin="6dp" />
</LinearLayout>
Hi all, this is my layout and I have an issue that if i put smaller image for example 60*60 - px to this layout my view is just around 60 pixel tall. but the image is stretched as it should be, I added minimum height to layout, but it does not solve my problem exactly because that number could be different based on the width of the device. What should I do to have always shown my whole imageview and have the wrap content as well, and not to play with some minHeight?

Prevent Image from scaling even though the imageView height = "match_parent"

I have this linear layout,
<?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:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:background="#color/white"
android:layout_marginTop="1dp"
android:weightSum="1" >
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="left|center"
android:padding="5dp"
android:text="Policy No."
android:textStyle="bold" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:src="#drawable/ic_launcher" />
</LinearLayout>
Now i want the image to not scale but the ImageView to match the height of the parent, the TextView height is set to wrap content and that cant be changed. Also, i can't set the imageView height as wrap_content, since it'll change the height of the overall Linear Layout and i can't afford that.
![Image of problem]http://imgur.com/gaef828
Now what i want is to have the image's size remain the same as it is the second row, even though the first row's height has increased.
Thanks in advance, any help would be appreciated.
add :
android:scaleType="centerInside"
to your ImageView
To perform no scaling, use
android:scaleType="center"
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
To get what you want, you can do this:
First give your imageviews same fixed height so they won't scale:
android:layout_height="25dp"
Than put gravity to center_vertical:
android:layout_gravity="center_vertical"
So now you have for each imageview:
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="25dp"
android:layout_weight="0.2"
android:src="#drawable/ic_launcher"
android:layout_gravity="center_vertical" />
It now no longer matters how may lines your textview has, your imageview will stay the same!
Ouput:
Hope this will help you with your problem.

android imageView scale

I have an ImageView which is populated from database (the image comes from database). in the database i have images both portrait and landscape!! how can i adjust the imageView to scale it self according to the image width and height. I have tried many ways but no result! any help please!!!!
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/slideshow"
android:orientation="horizontal"
android:padding="0dp"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginRight="5dp"
android:id="#+id/slide1"
android:src="#drawable/ddd"
/>
Try this code. adjustViewBounds attribute makes the ImageView the same size as image that you put in it.
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
If you need specific width or height change the wrap_content value.

Element relative height in layout

I have seen that the width of an element can be set to a fraction of the screen width by using a relative layout (code below showing ONLY the relevant properties):
<LinearLayout>
<ImageView
android:layout_width="0dp"
android:layout_weight=".40" />
</imageView>
<TextView
android:layout_width="0dp"
android_layout_weight=".60" />
</LinearLayout>
But ... apparently this same trick can NOT be done for assigning proportional height of an element. Eclipse complains if I attempt to set a layout_height of 0dp. What should I do if I want an image with a caption, where the image takes up 40% of the screen height and the caption below gets 60% ?
You can indeed assign weights for both horizontal and vertical orientations of a LinearLayout.
Horizontal orientation example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".40" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".60" />
</LinearLayout>
Vertical orientation example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".40" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".60" />
</LinearLayout>
As an aside, it's useful to know that you don't have to specify floating point numbers for the weights. Android will simply sum up all of the weights and then divide by the total to get the percentage for each. So using 4 and 6 respectively for the layout_weights would have worked just as well.
Add android:orientation="vertical" to your layout and then set layout_height=0dp and weight to wanted values.
So:
<LinearLayout
android:orientation="vertical">
<ImageView
android:layout_height="0dp"
android:layout_weight=".40" />
</imageView>
<TextView
android:layout_height="0dp"
android_layout_weight=".60" />
</LinearLayout>

Categories

Resources