Android LinearLayout: Give the first element remaing width - android

I am trying to achieve the following layout for 2 elements in a LinearLayout:
So to sum up:
- The second element should be allowed to fill as much as it needs
- The first element should be shortened down (textview ending on "...") if it is necessary.
- On bigger devices, both elements should be visible (if possible of course) and left aligned.
So here is my solution so far:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/filter_topbar_height"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/filter_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="0">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:lines="1"
android:clickable="false"
android:text="#string/filter_uppercase_colon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:lines="1"
android:ellipsize="end"
android:id="#+id/category_spinner"/>
</LinearLayout>
<LinearLayout
android:id="#+id/sorting_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:lines="1"
android:text="#string/sorting_uppercase_colon" />
<Spinner
android:id="#+id/sort_spinner"
style="#style/spinner"
android:lines="1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:spinnerMode="dialog"
tools:entries="#array/sorting_options"/>
</LinearLayout>
</LinearLayout>
The result of my current solution, is the opposite of what I want. Here the first element takes the width that it needs while the second one is pushed away to the right.

Change the first LinearLayout as
android:id="#+id/filter_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
And the second LinearLayout as
android:id="#+id/sorting_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0"
android:orientation="horizontal"

You should use ellipsize property of textview like
android:scrollHorizontally="true"
android:ellipsize="end"
android:maxLines="1"

Add this two properties in your text view
android:maxLines="1"
android:ellipsize="end"

Related

layout_gravity isn't working as expected - just partially

I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="#string/title_day"
android:textStyle="bold"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="Tuesday"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="#+id/tv_fail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+22"
android:textSize="16sp"
android:layout_gravity="end|center_vertical" />
</LinearLayout>
</LinearLayout>
And this looks like this:
And I want the last TextView with id tv_fail to be pinned to right end of screen. I suppose that
android:layout_gravity="end|center_vertical"
should handle it, but this instruction centers TextView vertically, but doesn't move it to end. How to fix it?
I suppose that
android:layout_gravity="end|center_vertical"
should handle it, but this instruction centers TextView vertically, but doesn't move it to end.
This is due to how LinearLayout works; your understanding of layout_gravity is generally correct.
LinearLayout takes its children and lays them out in a line, and the children will all be packed towards the "start" of the LinearLayout. In other words, a horizontal LinearLayout will ignore the horizontal component of the layout_gravity attribute of a child.
There are a few ways to work around this. The one that I think works best for your scenario is to make the TextView stretch to fill all the remaining space in the LinearLayout (using layout_weight), and then have the TextView position its text at the end of its content area (using gravity).
<TextView
android:id="#+id/tv_fail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+22"
android:textSize="16sp"
android:layout_gravity="center_vertical"
android:gravity="end"/>
If you just want to set text inside of your last TextView to end then you should use :
android:gravity="end"
for TextView gravity use:
android:layout_gravity="center"
Difference between android:gravity & android:layout_gravity is that first one arrange content inside of any view with given gravity while second one arranges view according to given gravity.
Updated code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="title_day"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="Tuesday"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="#+id/tv_fail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="+22"
android:textSize="16sp" />
</LinearLayout>

how to ensure the min space between two views in Relativelayout

I have two TextViews in a RelativeLayout. One to the left and the other one to the right. Both of them shows a string which may become very long. I want to make a min space of 10dp between two TextViews and let the right one have ellipse if no enough space.
I have below layout definition which does not work. The right TextView may cover the first one if it is very lone.
<RelativeLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_marginLeft="3dp">
<TextView
android:id="#+id/left_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="7dp"
android:gravity="bottom"
android:text=""/>
<TextView
android:id="#+id/right_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
/>
</RelativeLayout>
The only way I can do is to set the max length to the right one. But this is not what I want because if the left one is short, i want the right one to be longer than the maxWidth.
And when I added "toRightOf" this work but the textView width becomes too long for a short string shown in it. That is not acceptable
add Add android:layout_toRightOf="#+id/left_one in right_one textview
remove android:layout_alignParentRight="true" from right_one textview
replace android:layout_marginRight="10dp" by android:layout_marginLeft="10dp" in right_one textview
For right_one textview to remain right if it is short replace right_one textview portion by
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="10dp"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/left_one>
<TextView
android:id="#+id/right_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
/>
</RelativeLayout>
You can do like this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:id="#+id/left_one"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="7dp"
android:gravity="bottom"
android:layout_weight="0.3"
android:text="Left text "/>
<TextView
android:id="#+id/right_one"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
android:layout_weight="0.7"
android:layout_marginLeft="10dp"
android:text="edkjfcnrdskjvkjrdfvsxsdcndsjkvnjksdnvkj
sdjkvbksdbvkj zskjvn jsdnbjkvfdbde"/>
</LinearLayout>
Add:
android:layout_toLeftOf="#+id/right_one"
android:layout_marginRight="10dp"
to your left_one TextView.

Aligning two textviews in a listview

Here's what I have:
There are options and there are content to every option. Option numbers (A, B, C, D) are in a separate textview and their contents are in a separate textview.
All I'm trying is aligning the option number with the first line of the option content. I tried setting the constant paddingTop, but as the number of lines in the option-content changes, it goes out of alignment. Any suggestions upon how to do it?
Here's part of the xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/options"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:id="#+id/option_number"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="10"
android:text="A"
android:paddingLeft="5dp"
android:textSize="17sp"
android:textStyle="bold"
android:textColor="#color/charcoal"/>
<TextView
android:id="#+id/option_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="100"
android:textSize="17sp"
android:gravity="center|left"
android:paddingRight="20dp"
android:text="option content...."
android:textColor="#color/charcoal"/>
Can I do it by getting the paddingTop of option content dynamically and setting the same padding to the option number?
Try with below.
Replace this in your xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/options"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="5">
<TextView
android:id="#+id/option_number"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="5dp"
android:text="A"
android:maxLines="4"
android:textColor="#color/charcoal"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/option_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:maxLines="4"
android:text="option content...."
android:textColor="#color/charcoal"
android:textSize="17sp" />
</LinearLayout>
And It's Done.
Surely it will help you.
Set android:gravity="top" for option_number TextView android:gravity="top|left" for option_content. Or, User a Relative Layout and use layout_aligntop
Try setting android:layout_alignBaseline="#id/option_number" on option_content
You can use Relative layout instead of linear layout, but you wll have to change your xml a bit. So if you decide to use it you can just set the next property to first TextView
android:layout_alignTop="#+id/option_content"
It should help you.
use: android:layout_centerVertical="true".
Suggestion, can use the following three in combination to easily achieve what you want:
1) CenterVertical
2) ToRightOf
3) RelativeLayout.
e.g:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/options"
android:layout_width="match_parent"
android:layout_height="80dp">
<TextView
android:layout_centerVertical="true"
android:id="#+id/option_number"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:text="A"
android:paddingLeft="5dp"
android:textSize="17sp"
android:textStyle="bold"
android:textColor="#color/charcoal"/>
<TextView
android:layout_toRightOf="#id/option_number"
android:layout_centerVertical="true"
android:id="#+id/option_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:text="option content...."
android:textColor="#color/charcoal"/>

How to prevent "wrap_content" text view from pushing another view out of sight?

I have two text views in a layout. I would like to display them next to each other like so:
|[TextView1][TextView2] |
Width of the first text view can vary dramatically. From several symbols up to a 100 symbols, but I would like to ellipsize it if it is too long and TextView2 should always be visible. Like so:
|[TextView1TextView1Tex...][TextView2]|
I have tried the following layout, but it displays TextView2 always at the end of the screen:
[TextView1] [TextView2]|
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"/>
<TextView
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
I have tried to change the width of TextView1 from 0 to wrap_content, but then it pushes the TextView2 out of the sight like so:
|[TextView1TextView1TextView1Text...]|
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"/>
<TextView
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Any help would be much appreciated.
It may be a overkill, but TableLayout does the trick.
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/firstTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"/>
<TextView
android:id="#+id/secondTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"/>
</TableRow>
</TableLayout>
android:shrinkColumns="0" is the catch here. It tells the table to only shrink the first column while keeping the others untouched. The result is that the system will only resize the first column, i.e. your first TextView.
Try this solution, it works for me,
<?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="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_weight="1"
android:layout_width="0dp"
android:ellipsize="end"
android:maxLines="1"
android:layout_height="wrap_content"
android:text="TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView" />
<TextView
android:id="#+id/textView2"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:text="Second Textview" />
</LinearLayout>
![enter image description here][1]
Output: Check below Screen shot:
Not very proud of this solution, but it does the trick,
I have set width of both TextView1 and TextView2 to "wrap_content"
Then in the code I have set maxWidth of TextView1 to 80% of it's parent like so:
view.setMaxWidth((int)(((View)view.getParent()).getWidth() * 0.8));
When you specify weight for only one of the child elements,you are telling android that that view is the only on whose visibility you care about.However if you specify weight for both Child views.That ensures that both are visible.
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="end"/>
<TextView
android:layout_width="0dp"
android:layout_weight="0.25" //this makes sure both views are displayed
android:layout_height="wrap_content"/>
</LinearLayout>

Adding ScrollView to RelativeLayout changes position of wigdets

The following is the XML of my layout. It explicitly states that the title, time and description TextViews should be under the image of the alarm. However, as the screen shot shows, the TextViews have moved into the ImageView. Why does this happen and how can I fix this? The problem only started happening when I added the scrollview.
XML
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/img_alarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/alarm"
android:layout_centerInParent="true"
android:contentDescription="#string/content_description_layout_alarm"/>
<TextView
android:id="#+id/lbl_alarm_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dip"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:layout_below="#+id/img_alarm"
android:layout_alignLeft="#+id/img_alarm"
android:text="#string/empty"
/>
<TextView
android:id="#+id/lbl_alarm_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dip"
android:textStyle="bold"
android:layout_centerHorizontal="true"
android:layout_below="#+id/img_alarm"
android:layout_alignRight="#+id/img_alarm"
android:text="#string/empty"
/>
<TextView
android:id="#+id/lbl_alarm_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/lbl_alarm_title"
android:layout_alignLeft="#+id/lbl_alarm_title"
android:layout_alignRight="#+id/lbl_alarm_time"
android:maxLines="1"
android:ellipsize="marquee"
android:text="#string/empty"
/>
<Button
android:id="#+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/lbl_alarm_description"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:text="#string/stop_layout_alarm"
android:gravity="center" />
</RelativeLayout>
</ScrollView>
Image
Cute app :)
hmm... not sure why it's doing it, looks like you have the right code, without busting out eclipse. but i've also had some weird bugs with relativelayout that i didn't understand and didn't have time to debug.
i do know of an alternative way you can accomplish what you're looking for -
have a scrollview that encases a linearlayout instead of a relative layout. Do these things:
For the linearlayout, you can set orientation = vertical so that it's still a top down order.
For the part where you need two textviews where one is aligned to the right and the other is aligned to the right, you need another inner linearlayout with its orientation=horizontal. then have one element align parent left, and the other align parent right. add a weightSum=1 attribute to this linearlayout and have each of the two textviews layout_width=0.5 so that each is half the width of the screen
Apply a weightSum=1 attribute to your outer most linearlayout, and see each element inside so that it's layout_weight sum adds up to 1. layout_weight will allow an element to take up that much % of real estate on the screen. like if you set your imageView to have android:layout_weight=0.8 then it'll take up 80% of the screen... since mathematically, (layout_weight/weightSum) = (.08/1) = 80%
try to use that mechanism instead, and if should work :) if it's confusing i can give code
example
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">
<ImageView
android:id="#+id/img_alarm"
android:layout_width="match_parent"
android:layout_height="0dip"
android:src="#drawable/alarm"
android:layout_weight="0.7"
android:contentDescription="#string/content_description_layout_alarm"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1">
<TextView
android:id="#+id/lbl_alarm_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="20dip"
android:textStyle="bold"
android:text="#string/empty"
/>
<TextView
android:id="#+id/lbl_alarm_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="20dip"
android:textStyle="bold"
android:text="#string/empty"
/>
</LinearLayout>
<TextView
android:id="#+id/lbl_alarm_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.1"
android:maxLines="1"
android:ellipsize="marquee"
android:text="#string/empty"
/>
<Button
android:id="#+id/btn_stop"
android:layout_weight="0.1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:text="#string/stop_layout_alarm"
android:gravity="center" />
</LinearLayout>
</ScrollView>
i hope this deserves at least an upvote for the effort :D

Categories

Resources