I have a screen that contains some TextViews and an ImageView inside a LinearLayout with vertical orientation. I would like the whole thing to fit exactly in the screen (no matter what its size is) where the ImageView is the one that adjusts itself to accommodate this.
I've seen here a few variations of this question (including this) but didn't find anything that really answers my requirement.
So far i've used a solution which is not very "pretty", which is putting the entire LinearLayout inside a ScrollView, and use a custom ImageView that on its onMeasure method calculates the delta between the height of the ScrollView to the height of the screen. If the former is larger than the latter then the delta is subtracted from the ImageView's measured height.
This solution is not perfect and i would really like to know if there is a better one. Im sure there is.
Appreciate your help.
EDIT: here is the layout xml
<com.xxx.widgets.LockableScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res/com.venews"
android:layout_width="match_parent"
android:layout_height="match_parent"
custom:scrollable="false"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/login_horizontal_margin"
android:paddingRight="#dimen/login_horizontal_margin"
android:orientation="vertical">
<com.xxx.widgets.ResizableToFitScreenImageView android:id="#+id/login_logo_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/login_logo_margin"
android:layout_marginBottom="#dimen/login_logo_margin"
android:src="#drawable/ic_logo_and_name"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/login_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<TextView android:id="#+id/login_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/login_username"/>
(...Other stuff...)
</RelativeLayout>
</LinearLayout>
</com.xxx.widgets.LockableScrollView>
EDIT2: and here's a sketch that i hope will make things clearer.
The sketch is showing 2 different screen sizes cause this solution would need to support also different devices with different screen sizes.
On the ImageView, set android:layout_height="0dp" and android:layout_weight="1". This will cause it to fill the remaining space (more about layout_weight here).
<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="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Related
Objective: I am trying to make a MaterialCard with an Image inside it, as well as some text below the Image. This current layout will serve as a "menu" for the application, where the user can select where to navigate to.
Problem: The ImageView is appearing vertically centred in the MaterialCardView. I would like the ImageView to "stick" to the top of the MaterialCardView. There are large sections of MaterialCardView above and below the ImageView.
My XML Code:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true"
android:id="#+id/appBar">
<Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/design_default_color_primary_dark"
app:layout_scrollFlags="enterAlways">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/application_title"
android:textColor="#color/colorWhite"
android:textSize="24sp"/>
</Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/mealPlannerCardView"
android:contextClickable="true"
android:focusable="true"
app:cardBackgroundColor="#color/colorWhite">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:src="#drawable/wedding_dinner"
android:contentDescription="#string/wedding_background_cont_desc"/>
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="#string/mealPlannerTextView"
android:textColor="#color/design_default_color_primary_dark"/>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>
output
I tried to use layout_gravity="Top" but it made no difference.
EDIT
android:scaleType="fitStart" made the Image "stick" to the TOP of the MaterialCardView, but now very large space beneath the ImageView that requires scrolling to get to end.
Add the line below in your xml
android:layout_gravity="start|top"
See if this repositions the image for you. Worry about centring later if this works.
You might get the result you want by setting a scaleType for the image view.
Checkout this link: https://thoughtbot.com/blog/android-imageview-scaletype-a-visual-guide
It shows examples of each scaleType, it will help you to choose the right one to achieve the appearance you need.
This is happening because the Android framework is trying to maintain the aspect ratio in the face of your height and width constraints and default scale type.
There are more than one solutions to your problem and its for you to choose based on whose results are acceptable to you. All these solutions revolve around helping the framework with ImageView's aspect ratio. Let me try to put down the possible solutions that I can think of.
First solution can be as simple as changing the scale type on your ImageView as below:
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/wedding_dinner"/>
That will take away the white spaces but crop your image.
A slight variation of the above, where you can define a fixed height of the image. This is a surprisingly widely used solution as it provides a certain
<ImageView
android:layout_width="match_parent"
android:layout_height="240dp"
android:scaleType="centerCrop"
android:src="#drawable/wedding_dinner"/>
Finally, a more elegant and better solution is to provide a fixed aspect ratio to your images using a ConstrainLayout.
I would need some help with design a layout. I'm trying to design something like this:
My problem is that on some devices (with very small width) the imageViews are to big and are not visible. My aim is to make design with two equals columns and imageViews into. A imageView can be max so width as column (without padding). Probably should be scaled to max allow size. I've tried with GridLayout and TableLayout connected with scaleType but the imagesViews are always bigger then column.
Do have someone an idea how can I achieve similar effect?
Best regards,
Adrian
have you tried looking into imageView.AdjustViewBounds(true);
I've found a solution :)
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/awards_status"
android:orientation="horizontal">
<LinearLayout
android:layout_below="#+id/awards_status"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight=".5">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/awards_one_dwarf" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_below="#+id/awards_status"
android:orientation="vertical"
android:layout_weight=".5">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/awards_one_dwarf" />
</LinearLayout>
</LinearLayout>
Thanks and best regards.
I have read everything I can find, and I just can't figure this out. I have an XML with a heading, then a listview, and then 2 buttons on the bottom row. In order to make the layout look perfect, I have "hardcoded" the size (467dp) of the listview. This is fine on my Samsung Galaxy S4, but I'm not sure it will look appropriate on other phones of slightly different sizes. I tested it on a Galaxy 8" tab and it did not look right. I then tested it on a 10.1" tab and it (again) did not look right. Basically the bottom buttons were up in the middle of the screen. I got around this by creating layouts for sw600dp and sw720dp. For each of those I had to hardcode a different size for the listview. It would seem to me that there is a better way to have a heading-listview-button XML that would display (relatively) the same on any device. Can anyone please tell me how to to alter my XML so I don't have to hardcode the size of the listview?
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/title_line"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="#string/workout_locations">
</TextView>
<ListView
android:id="#+id/location_list"
android:layout_width="match_parent"
android:layout_height="467dp"
android:longClickable="true" >
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/help_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="#string/help_description"
/>
<ImageButton
android:id="#+id/add_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="#string/add_description"
/>
</LinearLayout>
</LinearLayout>
android:layout_weight="1 add this in the buttons
I wonder if this might help:
ensure that the entire layout is a relativeLayout, and inside it, put the listview
<ListView
android:id="#+id/location_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp" // the size of the buttons height
android:longClickable="true" >
</ListView>
and below it another relativelayout with the buttons inside it.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:layout_alignParentBottom="true">
<ImageButton
android:id="#+id/help_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="#string/help_description"
/>
<ImageButton
android:id="#+id/add_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="#string/add_description"
/>
If this still causes an issue, then you could write :
android:layout_above="#+id/relButtonLayout"
inside the listview.
Use layout_weight to take up as much room that can be afforded.
<ListView android:id="#+id/location_list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:longClickable="true" >
</ListView>
If you've hardcoded some sizes, you can bet it won't look good in most of the devices. In order to do that, it's always better using layout_height and layout_weight set to wrap_content or match_parent depending on what you need.
There's another important tool for the case you describe: layout_weight, as you might have already used. Messing with a ListView to fit the design you want can be hard at the first time, but once you discover how to set up its layout it's easy for the rest of them.
In my case, this definition always work as should:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#+id/mylistview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical" >
</ListView>
</LinearLayout>
Take a look at it: I've set a singular LinearLayout (in this case because it has more views than just the ListView I'm showing), but I'm setting the weight of that ListView to 1, being the sumWeights of that LinearLayout 1. This way you assure yourself the ListView will expand as long as it can, without the needing of hardcoding values.
It's just a matter of playing around with it for a while, but the less values you hardcode, the more adaptable will be on other devices.
I'm quite new in Android, so it'll probably be a stupid question, but here it goes.
I have a RelativeLayout of Activity. In this layout I have another Layout at bottom of a screen. Sometimes I hide it or make it visible, this matters not. Is it possible to make the another layout's height lets say 27% of total screen height? The idea is to keep the other content, except this layout on screen.
Have anyone tried something like this?
LinearLayout can handle this via android:layout_weight. For example, here is a layout containing three Button widgets, taking up 50%, 30%, and 20% of the height, respectively:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="50"
android:text="#string/fifty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="30"
android:text="#string/thirty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="20"
android:text="#string/twenty_percent"/>
</LinearLayout>
However, you cannot simply declare that an arbitrary widget at an arbitrary point in your layout file should take up an arbitrary percentage of the screen size. You are welcome to perform that calculation in Java and adjust your widget's LayoutParams as necessary, though.
you can try this, is more complexe but useful.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name" />
<LinearLayout
android:id="#+id/parent_of_bottom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true" >
<LinearLayout
android:id="#+id/content_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="27">
//Add your content here
</LinearLayout>
</LinearLayout>
I have an Android application that goes about like this:
<LinearLayout 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"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/toplayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.90" >
<Button
android:id="#+id/button_1_of_10"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/text_0x1701" />
<Button
android:id="#+id/button_2_of_10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="#+id/button_1_of_10"
android:layout_below="#+id/button_1_of_10"/>
<!--Another 8 buttons-->
<RelativeLayout
android:id="#+id/contentpane"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/button_1_of_10" >
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/actionbuttonslayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.10">
</RelativeLayout>
</LinearLayout>
I need the 10 buttons to fill up the entire height from the top to the footer (the 0.1 weighted RelativeLayout), while all the buttons keep an equal height. However, I want to know whether there is a kind of equivalent to the layout_weight from LinearLayout, but for RelativeLayouts, as it's not performant to have nested weights in LinearLayouts. I'm not really looking for other solutions, because I still have some thing to try, but I want to know whether or not this is possible?
My question, just to be clear, is: Is it possible to have an amount of Buttons with an equal height in a RelativeLayout and at the same time fill up all the available space?
To use weight you need to use a LinearLayout, just make a linear layout with the buttons take the space you want and then on each button inside have android:layout_height="0dp" and also a android:layout_weight="1"
You don't need to sum all the weights to 1, just think of items with the same weight have the same size