How to `wrap_content` while autosizing an Android TextView? - android

Consider this layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:autoSizeTextType="uniform"
android:gravity="center"
android:maxLines="1"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_max="50dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
Because of the height_max constraint this leads to a TextView where the text fills the vertical space but there's a lot of horizontal padding inside of the TextView:
What I want is for the width of that TextView to be set such that it matches the width of the autosized text content. But when I set android:layout_width="wrap_content" the width gets set based on the non-autosized text content:
Is there any way to get the best of both worlds---have the text autosize based on a known height, and then set the width based on the width of the autosized text?

Google's developer documentation specifically recommends against using wrap_content with autosized TextViews:
Note: If you set autosizing in an XML file, it is not recommended to use the value "wrap_content" for the layout_width or layout_height attributes of a TextView. It may produce unexpected results.
If you simply want your text to have a height of 50dp instead of 50sp, you could set the textSize to 50dp. But I suspect your goal is to have a textView that will autosize the text smaller based on layout constraints, and that solution won't do the job.
If you really can't have the extra horizontal space on your TextView from using a width of match_parent or 0dp, you could try programmatically setting the textview width layout parameter based on measuring the text with a TextPaint after the layout is created:
textView.post(new Runnable() {
#Override
public void run() {
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(textView.getTextSize());
float width = textPaint.measureText(textView.getText().toString());
ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
layoutParams.width = (int)width;
textView.setLayoutParams(layoutParams);
}
});
Keep in mind that if you go this route, you'll probably want to add some left and right padding to it. TextViews have a sort of internal padding, even if you set their padding to zero - but that gets overridden when the width parameter is set directly.

Try using 0dp (which equals MATCH_CONSTRAINT) for the android:layout_width attribute of the TextView.

It sounds like you want the display ratio of the text to change, for the text to act akin to scaleXY for an ImageView. Autosize does not do that. Rasterizing and scaling up is a bad approach as it will result in half-pixels. You could rasterize at the desired width and then squash the height, scaling the height down to minimise the distortion.

You can try this
<TextView
android:id="#+id/vName"
android:layout_width="56dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Groupa"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="20sp"
app:autoSizeTextType="uniform"
/>

Related

Setting an item to appear next to a recycler view keeps appearing on top [duplicate]

I would like to constrain a View's left and right sides to it's parent view's margins and make it fill the allotted space. However, setting width to either match_parent or wrap_content appears to produce the same result.
Is there something equivalent to match_constraints (as opposed to match_parent and wrap_content)? Do match_parent and wrap_content affect the layout or are they ignored in the new constraint layout?
match_parent is not allowed. But you can actually set width and height to 0dp and set either top and bottom or left and right constraints to "parent".
So for example if you want to have the match_parent constraint on the width of the element, you can do it like this:
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
match_parent is not supported, so use android:layout_width="0dp". With 0dp, you can think of your constraints as 'scalable' rather than 'filling whats left'.
Also, 0dp can be defined by a position, where match_parent relies on it's parent for it's position (x,y and width, height)
Apparently match_parent is :
NOT OK for views directly under ConstraintLayout
OK for views nested inside of views that are directly under ConstraintLayout
So if you need your views to function as match_parent, then:
Direct children of ConstraintLayout should use 0dp
Nested elements (eg, grandchild to ConstraintLayout) can use match_parent
Example:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp">
<android.support.design.widget.TextInputLayout
android:id="#+id/phoneNumberInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<android.support.design.widget.TextInputEditText
android:id="#+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.TextInputLayout>
match_parent is not supported by ConstraintLayout. Set width to 0dp to let it match constraints.
From the official doc:
Important: MATCH_PARENT is not recommended for widgets contained in a
ConstraintLayout. Similar behavior can be defined by using
MATCH_CONSTRAINT with the corresponding left/right or top/bottom
constraints being set to "parent".
So if you want achieve MATCH_PARENT effect, you can do this:
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
You can check your Adapter.
1 - MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater);
2 - MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater, viewGroup, false);
I had a same problem like you when I used 1.
You can try 2.
For making your view as match_parent is not possible directly, but we can do it in a little different way, but don't forget to use Left and Right attribute with Start and End, coz if you use RTL support, it will be needed.
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
in the office doc:
https://developer.android.com/reference/android/support/constraint/ConstraintLayout
When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space.
Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
Important: MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent"
set width or height(what ever u need to match parent ) to 0dp and set margins of left , right, top, bottom to act as match parent
If you want TextView in the center of parent..
Your main layout is Constraint Layout
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/logout"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:gravity="center">
</androidx.appcompat.widget.AppCompatTextView>

xamarin android How to increase multiline edit text height with screen height?

I want to manage multi line edit text control's height with respect to device screen height. Height should be 40% of screen.
I have used max lines, lines and min lines properties. If I set these properties then height does change but if screen height changes or device shifted to horizontal then edit text goes out of the screen. in short, multi line edit text height must be dynamic with screen size. It should shrink and expand as other control does with screen size.
Screenshot:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusableInTouchMode="true"
android:background="#e8eeff">
<EditText
android:id="#+id/etTextMultiLine"
android:inputType="textMultiLine"
android:gravity="top|left"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:hint="Enter a Text"
android:background="#layout/EditTextStyle"
android:textColorHint="#404144"
android:textColor="#404144"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:padding="5dp" />
Since you wish to achieve sizes with percentages, consider using PercentFrameLayout as your EditText's parent and just match both weight and height. The documentation says PercentFrameLayout is deprecated, so consider the replacement suggested, ConstraintLayout.

Why wrap_content has no effect?

Set wrap_content in RecycleView holder:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#android:color/black">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView3"
android:textColor="#android:color/white"
android:textSize="17dp"
android:background="#drawable/bubbleblue170x140_2" />
</RelativeLayout>
But text in TextView is not wrapped, there is a lot of empty space in the bubble, inside TextView.
How can I force to see something like this in iOS version:
In Android using 9-patch image as background.
The height of your text view is wrap and the big size is becuase of your 9patch image (probably having a big size)
And the width of that is match parent as you wanted in xml layput.
Just change the size of your 9 patch and make the width wrap content too
Resize your 9patch. You should also change the RelativeLayout's height and width to wrap_content. Or, even better, you should remove the RelativeLayout (it seems useless).

Set width to match constraints in ConstraintLayout

I would like to constrain a View's left and right sides to it's parent view's margins and make it fill the allotted space. However, setting width to either match_parent or wrap_content appears to produce the same result.
Is there something equivalent to match_constraints (as opposed to match_parent and wrap_content)? Do match_parent and wrap_content affect the layout or are they ignored in the new constraint layout?
match_parent is not allowed. But you can actually set width and height to 0dp and set either top and bottom or left and right constraints to "parent".
So for example if you want to have the match_parent constraint on the width of the element, you can do it like this:
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
match_parent is not supported, so use android:layout_width="0dp". With 0dp, you can think of your constraints as 'scalable' rather than 'filling whats left'.
Also, 0dp can be defined by a position, where match_parent relies on it's parent for it's position (x,y and width, height)
Apparently match_parent is :
NOT OK for views directly under ConstraintLayout
OK for views nested inside of views that are directly under ConstraintLayout
So if you need your views to function as match_parent, then:
Direct children of ConstraintLayout should use 0dp
Nested elements (eg, grandchild to ConstraintLayout) can use match_parent
Example:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp">
<android.support.design.widget.TextInputLayout
android:id="#+id/phoneNumberInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<android.support.design.widget.TextInputEditText
android:id="#+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.TextInputLayout>
match_parent is not supported by ConstraintLayout. Set width to 0dp to let it match constraints.
From the official doc:
Important: MATCH_PARENT is not recommended for widgets contained in a
ConstraintLayout. Similar behavior can be defined by using
MATCH_CONSTRAINT with the corresponding left/right or top/bottom
constraints being set to "parent".
So if you want achieve MATCH_PARENT effect, you can do this:
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
You can check your Adapter.
1 - MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater);
2 - MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater, viewGroup, false);
I had a same problem like you when I used 1.
You can try 2.
For making your view as match_parent is not possible directly, but we can do it in a little different way, but don't forget to use Left and Right attribute with Start and End, coz if you use RTL support, it will be needed.
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
in the office doc:
https://developer.android.com/reference/android/support/constraint/ConstraintLayout
When a dimension is set to MATCH_CONSTRAINT, the default behavior is to have the resulting size take all the available space.
Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
Important: MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to "parent"
set width or height(what ever u need to match parent ) to 0dp and set margins of left , right, top, bottom to act as match parent
If you want TextView in the center of parent..
Your main layout is Constraint Layout
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/logout"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:gravity="center">
</androidx.appcompat.widget.AppCompatTextView>

Repeated background affects TextViews height

I have a Image that I want to repeat on the x axis to match the width.
repeating_section_header.xml :
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/table_section_header_light"
android:tileMode="repeat" />
so far so good.
Now I set this as background of a TextView:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_headline_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/repeating_section_header"
android:gravity="left|center_vertical"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold"/>
But now the the TextViews height is the height of #drawable/table_section_header_light, even if I have set TextViews height to wrap_content.
Any idea how to fix that (make the TextViews height to wrap content)
One way of doing this is by programmatically determining the height of the textview with just the text, and fixing the height, and the setting the background drawable. This way, it will adjust to the height of your textview depending on how many lines is used.
Java:
TextView v = (TextView) findViewById(R.id.row_headline_text);
v.setText("<your text here>");
v.measure(android.view.View.MeasureSpec.UNSPECIFIED, android.view.View.MeasureSpec.UNSPECIFIED);
android.view.ViewGroup.LayoutParams params = v.getLayoutParams();
params.height = v.getMeasuredHeight();
v.setLayoutParams(params);
v.setBackgroundResource(R.drawable.table_section_header_light);
xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_headline_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold" />
If you okay with this technique, try it:
Wrap your TextView into a RelativeLayout.
Add a View as the first child in this RelativeLayout. (let the TextView be the second child)
Remove your background from the TextView to this new View
Set the layout params of your TextView (AlignLeft, AlignRight, AlignTop, AlignBottom) to #+id/row_headline_text
This should work. If your TextView's parent is already a RelativeLayout, you won't need the new RelativeLayout.

Categories

Resources