Why don't my multiline textviews have the same height? - android

I have 3 textviews with 2 lines. I placed them in the horizontal LinearLayout with same weight. The problem is that when I put text into this TextViews, they have different heights if text take up 1 line or 2 lines. This behavior is strange.
I need 3 text views with the same height regardless to the text length.
my_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="bottom">
<TextView
style="#style/style"
android:text="TextView1" />
<TextView
style="#style/style"
android:text="Long text Textview2" />
<TextView
style="#style/style"
android:text="TextView3" />
</LinearLayout>
styles.xml:
<style name="style">
<item name="android:layout_width">0dp</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#color/black</item>
<item name="android:background">#color/white</item>
<item name="android:lines">2</item>
<item name="android:textSize">#dimen/txt_size_30</item>
</style>

You need to set layout_height with some height rather than using wrap_content.
WRAP_CONTENT :
Special value for the height or width requested by a View.
WRAP_CONTENT will change the height according to view requirement.
Update
You can use ConstraintLayout. Here all the TextView height matches with height of long textView(TextView 2)
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#dedede"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/textView2"
app:layout_constraintBottom_toBottomOf="parent"
android:text="textview 1"
app:layout_constraintTop_toTopOf="#id/textView2"
/>
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:background="#dedede"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/textView1"
app:layout_constraintEnd_toStartOf="#id/textView3"
app:layout_constraintBottom_toBottomOf="parent"
android:text="long textView 2"
/>
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:background="#dedede"
android:layout_height="0dp"
app:layout_constraintStart_toEndOf="#id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="textView 3"
app:layout_constraintTop_toTopOf="#id/textView2"
/>
</android.support.constraint.ConstraintLayout>

Related

View in ConstraintLayout does not fit within screen bounds

I'm trying to align 3 TableLayouts within a ConstraintLayout. I want the table with the MaterialButtons to have 1:1 dimension ratio, while the table on the top and on start still completely remains within the bounds of the screen. This is what it currently looks like:
The definition of this TableLayout:
<TableLayout
android:id="#+id/play_field_table"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/play_field_row_values_table"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.7">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton style="#style/field_unpainted" />
...
<com.google.android.material.button.MaterialButton style="#style/field_unpainted" />
</TableRow>
...
</TableLayout>
The definition of the button's style:
<style name="field_unpainted" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="android:layout_margin">0dp</item>
<item name="android:padding">0dp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:insetTop">0dp</item>
<item name="android:insetBottom">0dp</item>
<item name="android:textAlignment">center</item>
<item name="android:textStyle">bold</item>
<item name="android:backgroundTint">#ffffff</item>
<item name="android:strokeColor">#000000</item>
<item name="cornerFamily">cut</item>
<item name="cornerRadius">0dp</item>
</style>
The definition of the TableLayout on the start:
<TableLayout
android:id="#+id/play_field_row_values_table"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginLeft="8dp"
app:layout_constraintBottom_toBottomOf="#+id/play_field_table"
app:layout_constraintEnd_toStartOf="#+id/play_field_table"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/play_field_table">
<TableRow
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="end|center_vertical"
android:text="1 1"
android:textAlignment="gravity"
android:textColor="#color/black" />
</TableRow>
...
</TableLayout>
This is the definition of the TableLayout on the top:
<TableLayout
android:id="#+id/play_field_column_values_table"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/play_field_table"
app:layout_constraintEnd_toEndOf="#+id/play_field_table"
app:layout_constraintStart_toStartOf="#+id/play_field_table">
<TableRow
android:layout_width="0dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|bottom"
android:text="1"
android:textAlignment="gravity"
android:textColor="#color/black" />
...
</TableRow>
...
</TableLayout>
I've tried setting the layout_constraintDimensionRatio to 1:1 on the "id/play_field_table", but then it stretches out of the screen:
Also tried setting the layout_constraintDimensionRatio to 1:1 in the button style, but then the buttons either are just not displayed or the same result as above.
I feel like the ratios should be both set for the buttons and for the table, just can't figure out correct combinations. Any advice?
I managed to fix the issue by setting the following values for the "#+id/play_field_table" TableLayout:
Changed "layout_height" from "wrap_content" to "0dp" value
Added "layout_constraintDimensionRatio" with "1:1" value
Added "layout_weight" with "1" value to the TableRows inside the TableLayout

How to make horizontal Linear Layout Child wrap its content? [duplicate]

This question already has answers here:
Android - LinearLayout Horizontal with wrapping children
(12 answers)
Closed 1 year ago.
As the title suggests in my case the child view is a TextView with some content. and I want it to be one per line
So putting layout_width to 0dp and adding layout_weight to 1 did not work, Im assuming that because its the only one in its line so 1 is the highest wight... not sure about it though
this is the xml:
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</LinearLayout>
At the end I want them one after another vertically (one on each row)
with horizontal size as their text length (content)
Is this even possible with Linear Layout?
Thanks
EDIT:
As #Ajil O answer is working, my own problem still remains. I isolated the main difference.
In my project Im adding the Text Views from the code using Inflate because I have default styling.
Inflating Code:
final LinearLayout tagAreaView = (LinearLayout) findViewById(R.id.tagsVerticalLineup);
TextView tag = (TextView) getLayoutInflater().inflate(R.layout.answer_tag, null);
int tagId = someListArray.size();
tag.setId(tagId);
tag.setText(someChangingObject.text);
tagAreaView.addView(tag, tagId);
Text View answer_tag:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/SelectedTagAnswer" />
style xml SelectedTagAnswer:
<style name="SelectedTagAnswer">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginStart">8dp</item>
<item name="android:layout_marginEnd">16dp</item>
<item name="android:background">#drawable/selected_answer</item>
<item name="android:drawablePadding">8dp</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:drawableStart">#drawable/ic_cross_round</item>
<item name="android:elevation">3dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:paddingEnd">25dp</item>
<item name="android:paddingStart">15dp</item>
<item name="android:paddingTop">8dp</item>
</style>
NOTE:
When inserting a simple Text View to xml that uses same style,
it works like in #Ajil O answer. Some thing in the inflating process messing it up.
Make the LinearLayout width to match_parent and height to wrap_content
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
If you want the TextView to occupy 1 line use android:maxLines="1" attribute
EDIT
The TextView are all in color now. You can see that the TextView is as wide as it's content.
The container, LinearLayout is shaded in the light violet(?) color. This LinearLayout has to be atleast as wide as the longest TextView or the view (or it's content) would get clipped.
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:background="#AAAAFF"
android:layout_gravity="center">
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#080"
android:text="small text"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slightly longer text"
android:background="#400"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
<TextView
android:layout_margin="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="loooooooooooooooooong text"
android:background="#008"
android:textColor="#FFF"
android:textSize="18sp"
android:maxLines="1"/>
</LinearLayout>
Finally found a solution, So turns out Android wont refresh layout of views with wrap_content once it has been displayed.
As found in this answer WRAP_CONTENT not working after dynamically adding views
So my problem was inflating the view and then adding content (text).
To over come that, I set again the the height and width like so:
tag.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
Now, if all from Ajil O answer is implemented, it is working!
Hope this edge case will come handy to someone in the future
Just use wrap_content parameter in your android:layout_widthand you will be fine You are using 0dp now:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/tagsVerticalLineup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
It is preferable that you use the ContrainstLayout and you can manipulate any event to the dimensions that you want
Try this
make the parent layout's Height and Width=match_parent
textView make width match_parent so that you can use textalignment=centre or you can use gravity=centre
<LinearLayout
android:id="#+id/tagsVerticalLineup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>

Too long TextView makes other Views disappear

How to stop checkbox from disappearing in code below when text in the TextView is too long? I'm not interested in hardcoding max_width for the TextView and I want to display my whole text.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight="0"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="1"/>
</LinearLayout>
styles.xml
<style name="Text">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:padding">#dimen/margin</item>
<item name="android:textSize">#dimen/text</item>
<item name="android:textAlignment">center</item>
</style>
I would use weight. Add android:weightSum to your LinearLayout with value 1.
For each element in your LinearLayout add weight. For example 0.8 for textview and 0.2 for Checkbox.
Then set width to 0dp for each element !
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight="0.8"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="0.2"/>
</LinearLayout>
And update your style :
<style name="Text">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">0dp</item>
<item name="android:padding">#dimen/margin</item>
<item name="android:textSize">#dimen/text</item>
<item name="android:textAlignment">center</item>
</style>
If you are about to display large data on textview, i suggest to use scroll view in your parent layout.
I'm late for this but I hope to help smn with this issue. Have same problem checkBox make TextView unreachable for LinearLayout, both checkBox and textView need to have this line in xml:
android:layout_gravity="center_vertical"
use text view weight = 1 and other view as wrap_content so size of other view not change according your text
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight=""
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="wrap_content"/>
</LinearLayout>
If you want text to go in new line (use RelativeLayout):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="#id/checkbox" />
</RelativeLayout>
Another solution is to use this lib to shrink text:
https://github.com/grantland/android-autofittextview
I would suggest to use RelativeLayout to maintain uniformity in UI. Below is sample Relative layout code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_toLeftOf="#+id/cb"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_alignParentEnd="true"/>
</RelativeLayout>

Android: Justify text to the right in nested Linear Layout

I am having a very hard time justifying TextViews to the left in Android. I looked here but did not have success. The TextViews I want to justify are in Linear Layouts nested in a parent Linear Layout:
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<Button
android:text="New Button"
android:id="#+id/button1"
style="#style/calibrate_button" />
<TextView
android:text="#string/calibrate"
android:id="#+id/textView3"
style="#style/calibrate_text" />
</LinearLayout>
Style:
#color/White
20sp
wrap_content
wrap_content
?android:attr/textAppearanceLarge
right
<style name="calibrate_button">
<item name="android:background">#fcfcfc</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
Lik Gil said, you can use this way :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" >
<Button
android:id="#+id/button1"
style="#style/calibrate_button"
android:layout_alignParentLeft="true"
android:text="New Button" />
<TextView
android:id="#+id/textView3"
style="#style/calibrate_text"
android:text="#string/calibrate"
android:layout_alignParentRight="true" />
</RelativeLayout>

How to correctly set up this layout

I have this as part of a layout
<RelativeLayout
android:layout_weight="1"
android:layout_height="match_parent"
android:id="#+id/home_btn"
style="#style/Home_Button">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center"
android:id="#+id/a"
android:text="#string/centres"/>
<ImageView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_above="#id/a"
android:src="#drawable/ic_home_btn"/>
</RelativeLayout>
I need the TextView to be centered in the RelativeLayout, and the ImageView to be above the TextView, with a set dp offset (e.g. a 10dp gap between the image and the text)
I've tried various different methods and nothings worked so far. How can I correctly get this to work?
Oh, here's the style
<style name="Home_Button_NL">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">match_parent</item>
<item name="android:background">#drawable/home_button</item>
<item name="android:textColor">#color/white</item>
<item name="android:gravity">center</item>
<item name="android:layout_marginTop">#dimen/padding_tiny</item>
</style>
Make use of android:drawableLeft/Right/Top/Bottom to position an Image to the TextView. Furthermore you can use some padding between the TextView and the drawable with android:drawablePadding=""
Use it like this:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center"
android:drawableTop="#drawable/ic_home_btn"
android:drawablePadding="10dp"
android:id="#+id/a"
android:text="#string/centres"/>
This way you only have to position one View in the center of the RelativeLayout.
Note that you can't scale your Image this way. I suggest this because there is no scaling in your setup.
Use android:center_horizontal = "true" and alignParentBottom = "true"in your TextView
<RelativeLayout
android:layout_weight="1"
android:layout_height="match_parent"
android:id="#+id/home_btn"
style="#style/Home_Button">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center"
android:id="#+id/a"
android:text="#string/centres"
android:centerInParent="true" // center the textview in it's parent
"/>
<ImageView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_above="#id/a"
android:src="#drawable/ic_home_btn"
android:layout_centerHorizontal="true" // center imageview horizontally
android:layout_marginTop="YOUR MARGIN HERE"
/>
</RelativeLayout>
This may help !
Have you tried:
android:paddingBottom="10dp"

Categories

Resources