How to make layout with View fill the remaining space? - android

I'm designing my application UI. I need a layout looks like this:
(< and > are Buttons). The problem is, I don't know how to make sure the TextView will fill the remaining space, with two buttons have fixed size.
If I use fill_parent for Text View, the second button (>) can't be shown.
How can I craft a layout that looks like the image?

Answer from woodshy worked for me, and it is simpler than the answer by Ungureanu Liviu since it does not use RelativeLayout.
I am giving my layout for clarity:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width = "80dp"
android:layout_weight = "0"
android:layout_height = "wrap_content"
android:text="<"/>
<TextView
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:layout_weight = "1"/>
<Button
android:layout_width = "80dp"
android:layout_weight = "0"
android:layout_height = "wrap_content"
android:text=">"/>
</LinearLayout>

If <TextView> is placed in a LinearLayout, set the Layout_weight proprty of < and > to 0 and 1 for the TextView.
If you're using a RelativeLayout, align < and > to the left and right and set "Layout to left of" and "Layout to right of" property of the TextView to the ids of < and >.

If you use RelativeLayout, you can do it something like this:
<RelativeLayout
android:layout_width = "fill_parent"
android:layout_height = "fill_parent">
<ImageView
android:id = "#+id/my_image"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentTop ="true" />
<RelativeLayout
android:id="#+id/layout_bottom"
android:layout_width="fill_parent"
android:layout_height = "50dp"
android:layout_alignParentBottom = "true">
<Button
android:id = "#+id/but_left"
android:layout_width = "80dp"
android:layout_height = "wrap_content"
android:text="<"
android:layout_alignParentLeft = "true"/>
<TextView
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:layout_toLeftOf = "#+id/but_right"
android:layout_toRightOf = "#id/but_left" />
<Button
android:id = "#id/but_right"
android:layout_width = "80dp"
android:layout_height = "wrap_content"
android:text=">"
android:layout_alignParentRight = "true"/>
</RelativeLayout>
</RelativeLayout>

Using a ConstraintLayout, I've found something like
<Button
android:id="#+id/left_button"
android:layout_width="80dp"
android:layout_height="48dp"
android:text="<"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/left_button"
app:layout_constraintRight_toLeftOf="#+id/right_button"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/right_button"
android:layout_width="80dp"
android:layout_height="48dp"
android:text=">"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
works. The key is setting the right, left, top, and bottom edge constraints appropriately, then setting the width and height to 0dp and letting it figure out it's own size.

It´s simple
You set the minWidth or minHeight, depends on what you are looking for, horizontal or vertical.
And for the other object(the one that you want to fill the remaining space) you set a weight of 1 (set the width to wrap it´s content), So it will fill the rest of area.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|left"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:layout_width="80dp"
android:layout_height="fill_parent"
android:minWidth="80dp" >
</LinearLayout>

you can use high layout_weight attribute. Below you can see a layout where ListView takes all free space with buttons at bottom:
<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"
tools:context=".ConfigurationActivity"
android:orientation="vertical"
>
<ListView
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1000"
/>
<Button
android:id="#+id/btnCreateNewRule"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Create New Rule" />
<Button
android:id="#+id/btnConfigureOk"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Ok" />
</LinearLayout>

You should avoid nesting 2 relative layout since relative layout always make 2 pass for drawing (against 1 for any other type of layout). It becomes exponential when you nest them. You should use linear layout with width=0 and weight=1 on the element you want to fill the space left.
This answer is better for performance and the practices. Remember: use relative layout ONLY when you don't have other choice.
<?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">
<ImageView
android:id="#+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<Button
android:id="#+id/prev_button"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text="<" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:gravity="center"
android:text="TextView" />
<Button
android:id="#+id/next_button"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:text=">" />
</LinearLayout>
</LinearLayout>

For those having the same glitch with <LinearLayout...> as I did:
It is important to specify android:layout_width="fill_parent", it will not work with wrap_content.
OTOH, you may omit android:layout_weight = "0", it is not required.
My code is basically the same as the code in https://stackoverflow.com/a/25781167/755804 (by Vivek Pandey)

When using a relative layout, you can make a view stretch by anchoring it to both of the views it's supposed to stretch toward. Although the specified height will be disregarded, Android still requires a height attribute, which is why I wrote "0dp". Example:
<View
android:id="#+id/topView"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_marginTop="8dp"/>
<View
android:id="#+id/stretchableView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/topView"
android:layout_above="#+id/bottomView"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:adjustViewBounds="true"/>
<View
android:id="#id/bottomView"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="16dp"/>

You can use set the layout_width or layout_width to 0dp (By the orientation you want to fill remaining space).
Then use the layout_weight to make it fill remaining space.

use a Relativelayout to wrap LinearLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:round="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text="<"/>
<TextView
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:layout_weight = "1"/>
<Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text=">"/>
</LinearLayout>
</RelativeLayout>`

i found
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:fontFamily="casual"
android:text="(By Zeus B0t)"
`` android:textSize="10sp"
android:gravity="bottom"
android:textStyle="italic" />

Related

Android: horizontal LinearLayout does not lay out elements as expected

I create a horizontal LinearLayout that contains an EditText and a button. The button should be as narrow as possible, and the EditText should occupy the entire remaining space.
Like that:
I write this code:
<LinearLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/editTextToSpeak"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ems="10"
android:hint="#string/text_to_speak"
android:inputType="text" />
<Button
android:id="#+id/saveCard"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/save_card" />
</LinearLayout>
And I get this picture:
The button is not visible at all, and the height of the EditText has doubled.
How to make these elements look like in the first picture?
You can easily archive that by using android:layout_weight="1" and android:layout_width = "0dp" in your EditText, so it will take the rest of the space except your button's area.
<LinearLayout
android:id = "#+id/textInputLayout"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:orientation = "horizontal">
<EditText
android:layout_weight="1"
android:id="#+id/editTextToSpeak"
android:layout_width="0dp"
android:layout_height="match_parent"
android:ems="10"
android:hint="#string/text_to_speak"
android:inputType="text" />
<Button
android:id="#+id/saveCard"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/save_card" />
</LinearLayout>
Hope that help :)
You can also be implemented using a Relative layout in android.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<EditText
android:id="#+id/editTextToSpeak"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/text_to_speak"
android:inputType="text"
android:layout_toStartOf="#+id/saveCard"/>
<Button
android:id="#+id/saveCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/save_card"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
I hope it helps.)
Use android:weightSum & android:weight. It will give you the ability to fix the sizes either vertically or horizontally.
<LinearLayout
android:id = "# + id/textInputLayout"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:orientation = "horizontal"
android:weightSum="3">
<EditText
android:id = "#+id/editTextToSpeak"
android:layout_width ="match_parent"
android:layout_height = "match_parent"
android:ems = "10"
android:hint = "#string/text_to_speak"
android:inputType = "text"
/>
<Button
android:id = "#+id/saveCard"
android:layout_width = "wrap_content"
android:layout_height = "match_parent"
android:text = "# string/save_card"
android:layout_weight="1"/>

not enough space for ListView

i have TextView and ListView on LinearLayout, unfortunately on small screen i have not enough space for ListView(i mean it display about 0.5row). Is it possible to scroll up everything together.? Is in SDK any alternative for ListView that i can use for it.? Or maybe You got other idea how to make it userfriendly.?
layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" >
<TextView
android:id="#+id/textView5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/studio"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2" >
</ListView>
</LinearLayout>
There is a better solution for this instead of adding title to the main layout you can add that title to another layout and inflate that layout as header to the listview.
Like this -:
LayoutInflater inflater = getLayoutInflater();
ViewGroup header = (ViewGroup)inflater.inflate(R.layout.title, myListView, false);
myListView.addHeaderView(header, null, false);
layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
title.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" >
<TextView
android:id="#+id/textView5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/studio"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Your problem is the sizes and weights that you have assigned to various components. Assign proper weights to the listview and the text views layouts and it should work fine on any screen. e.g do some thing like this :
<LinearLayout
android:id= "#+id/parent_layout"
android:layout_height = "match_parent"
android:layout_width = "match_parent"
android:weightSum = "1.0"
android:orientation = "vertical" >
<LinearLayout
android:id= "#+id/text_views_layout"
android:layout_height = "0dp"
android:layout_width = "match_parent"
android:layout_weight = "0.7"
>
<!-- place your text views here -->
</LinearLayout>
<ListView
android:id ="#+id/list"
android:layout_height = "0dp"
android:layout_width ="match_parent"
android:layout_weight = "0.3"
>
</ListView>
</LinearLayout>
Note: you can specify any weights proportion for the textview_layout and the listview (i have set it to 0.7 : 0.3) but remember what ever weights you assign to them, they must sum up to the weight sum of the parent which is 1.0 in this case. Otherwise you might see unexpected behaviour.
Put the LinearLayout with the 2 TextViews as a header view for the ListView using addHeaderView
There is ScrollView which could solve your problem, for example
<ScrollView>
<LinearLayout>
......
//More code here
</LinearLayout>
</ScrollView>
but remember Scroll View can only have only and only one child, and that child could have its own further child but ScrollView could have only one child. My this code is to give you idea it will not work by just copy and paste you have to made width , height etc adjustment according to your need

Android not resizing?

I am developing my app on a 4in emulator in Eclipse. My phone is a 4.6in android device and when I test it on there, the content doesn't scale correctly.
It looks like the phone keeps the content at the same size, and it just moves everything up and leaves the extra space empty.
From what I have read, I thought it was supposed to keep the same layout as long as I use dp and not in. Does that mean my images need to be dp as well?
Any suggestions?
EDIT:
Here is some code:
<?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="#drawable/tfltestbg2"
android:orientation="vertical" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="55dp"
android:background="#drawable/tfl_header_port"
android:gravity = "center_horizontal"
android:layout_gravity = "center_horizontal"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="horizontal"
android:layout_gravity = "center"
android:gravity = "center"
>
<Button
android:id="#+id/buttonTakePic"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:gravity = "left"
android:background="#drawable/takepic_button" />
<Button
android:id="#+id/mMegaGalleryButton"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity = "center"
android:background="#drawable/add_fotos" />
<Button
android:id="#+id/mGalleryButton"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:gravity = "right"
android:background="#drawable/selectpic"
android:paddingLeft = "10dp"
android:paddingRight = "10dp"/>
</LinearLayout>
<LinearLayout
android:id="#+id/image_container"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="center"
android:background="#drawable/outline_box"
android:gravity="center">
<FrameLayout
android:layout_width = "match_parent"
android:layout_height = "fill_parent"
android:gravity = "center"
android:layout_gravity = "center">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background = "#drawable/blank"
android:gravity="center" />
<ImageView
android:id="#+id/picsImage"
android:layout_width = "100dp"
android:layout_height = "100dp"
android:layout_gravity="center"
android:gravity="center"
android:background = "#drawable/picture_box"/>
</FrameLayout>
</LinearLayout>
<Button
android:id="#+id/mEditButton"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="#drawable/edit_pic_button" />
<View
android:layout_width="match_parent"
android:layout_height="10dp" />
<Button
android:id="#+id/buttonUploadPic"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="#drawable/upload_pic_button" />
</LinearLayout>
Use relative layout instead of linear layout and dont use hardcoded dimesions like 40dp,50dp if use app for different sizes of screen.
Relative layout
Problem in your layout is that you used fixed values in wrong places! Instead android:layout_width="100dp" in button (this in horizontal layout) you should use android:layout_width="fill_parent".
You have to set none zero value for layout_weight for this buttons so they could share space with other siblings in this layout.
Simplest way to convert fixed dp to weight:
change this:
android:layout_width="100dp"
to this:
android:layout_width="0dp"
android:layout_weight="100"
do it for all buttons and they will look exactly like they was in 4" and will scale perfect in any screen.

Android buttons width in proportion

I need to place 3 buttons i one line./Using LinearLayout/.
Problem is when change text on button. Width changes because of "android:layout_width="wrap_content". I want to be sure thab buttons will ocupy screen width i 4:4:2 proportion. Clause 'wrap_content' brokes this, but I can not use exact size because I don't know device screen width in design time.
Anybody knows easy way to solve this without using code?
Don't set their width to wrap_content. Set proportional weights instead:
<LinearLayout
...
layout_width = "match_parent"
layout_height = "wrap_content" />
<Button
....
layout_width = "0dp"
layout_height = "wrap_content"
layout_weight = 2 />
<Button
....
layout_width = "0dp"
layout_height = "wrap_content"
layout_weight = 2 />
<Button
....
layout_width = "0dp"
layout_height = "wrap_content"
layout_weight = 1 />
</LinearLayout>
try following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:weightSum="10" // SEE THIS IS 4+4+2 = 10
android:layout_centerHorizontal="true" >
<Button
android:layout_weight="4" // THIS IS 4
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:layout_weight="4" // THIS IS 4
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:layout_weight="2" // THIS IS 2
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</RelativeLayout>
should be
android:layout_weight="4dp"

Android: Vertical LinearLayout - Two image views, I want the bottom one to scale to be the width of the top one

I'm trying to get a vertical LinearLayout to display an imageview with a second imageview below it. I want the lower imageview to be the width of the top image view.
I'm trying the current layout xml:
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:layout_weight="1"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/spacer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/spacer"
/>
</LinearLayout>
</LinearLayout>
The images will be displayed with a 'spacer' which is the full width of the screen, rather than the width of the image. The spacer is a fading edge graphic and I want it to be the same width as the image above it.
Note: the image for the top imageview is set programatically and could be a landscape or portrait image.
Anyone any thoughts on how to achieve this?
Thanks in advance!
A RelativeLayout will do. Use layout_below to achieve the vertical ordering and layout_widht="match_parent" to make the bottom image view as wide as possible with layout_alignLeft and layout_alignRight constraints:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"/>
<ImageView
android:id="#+id/spacer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/image_view"
android:layout_alignLeft="#id/image_view"
android:layout_alignRight="#id/image_view"
android:background="#drawable/spacer" />
</RelativeLayout>
Sample output:
Using a slighly altered layout for demo purposes, warnings caused by missing contentDescriptions:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<ImageView
android:id="#+id/image_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:background="#f00"/>
<ImageView
android:id="#+id/spacer"
android:layout_width="fill_parent"
android:layout_height="10dp"
android:layout_below="#id/image_view"
android:layout_alignLeft="#id/image_view"
android:layout_alignRight="#id/image_view"
android:background="#0f0" />
</RelativeLayout>
(Yes I know. Old question but no good answers and got bumped up by Community.)
Hey r3mo use the following code you can get what you want to achieve
<RelativeLayout android:layout_height = "fill_parent" android:layout_width = "fill_parent">
<ImageView android:layout_width = "wrap_content"
android:layout_height = "wrap_content" android:id = "#+id/ImageView1"
android:src = "#drawable/spacer"/>
<ImageView android:layout_width = "wrap_content"
android:layout_height = "wrap_content" android:id = "#+id/ImageView2"
android:src = "#drawable/spacer"
android:layout_below = "#+id/ImageView1"/>
</RelativeLayout>
Use Table Layout Instead of Relative and LinearLayout To achieve this, as Table Layout Automatically provide same column with to all rows.

Categories

Resources