I use new autosize feature added in support library 26. I read a documentation which can be found here :
https://developer.android.com/preview/features/autosizing-textview.html
I suppose that it should work this way: You can enable auto-sizing with this attribute: app:autoSizeTextType="uniform". I think that TextView should use all available space to display a whole text (not just a part - it shouldn't be cropped) and the textSize should be as big as possible. If you need to limit a maximum or minimum size of the text then you can use these two attributes:
app:autoSizeMinTextSize="XXsp" // (you can also use px or dp values.)
or
app:autoSizeMaxTextSize="XXsp"
So far so good. Let's say that I need a TextView with 56dp width. I have texts with a different length and I want to set these texts to this TextView. It should be automatically resized so it displays the whole text (all characters + not cropped) in the biggest possible textSize.
This is my TextView:
<android.support.v7.widget.AppCompatTextView
android:id="#+id/vName"
style="#style/TextView.AutoSize"
android:layout_width="56dp"
android:gravity="bottom|center_horizontal"
android:maxLines="1"
app:autoSizeMinTextSize="1px"
app:autoSizeTextType="uniform"
app:layout_constraintBottom_toTopOf="#id/vGuideline"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
Unfortunately, the text view is cropped. I wanted to set this String as a text to the TextView above: "Groupa" but this is the result:
(TextView is inside ConstraintLayout with yellow circle background.)
As you can see the textview is not resized at all. Do you have any idea what to do?
Thanks.
Additional to the other correct answers I found another point which prevents autosizing to work.
Do not use android:singleLine="true" together with autosizing. Use the newer android:maxLines="1" instead.
I have tested this for a few situations, and have the below conclusion:
You must have bounded width and height. For example, if you set width to be match_parent but wrap_content for height, I think Android doesn't know that how high you want to stretch your text. In your example you don't have a specific height, so I think that's why it doesn't work.
For example:
I don't know why Android official document would use wrap_content as an example...
And as you can see I didn't use other attributes in my example, so it probably is not the problem of incorrect attributes.
And, yes, the TextView I am using is android.support.v7.widget.AppCompatTextView.
And as long as you are using support library 26.0.0 or above it is good enough.
EDIT:
As for ConstraintLayout, the principal is the same.
You should have both bounded width and height, which means either one of below for each dimension:
You have specified an absolute value for that dimension (width or height)
You have set Constraint to both directions
For example:
UPDATE: (2017-09-21)
I have tested that unfortunately it seems it does not support custom typeface yet, which is a function published together in support library v26...
I had the same issue.
I solved it by changing two lines in my gradle:
compile 'com.android.support:support-v4:26.0.1' and
compile 'com.android.support:appcompat-v7:26.0.1'
To fit longer texts you have to add all four options, like this:
<android.support.v7.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/your_string"
app:autoSizeTextType="uniform"
app:autoSizeMaxTextSize="13sp"
app:autoSizeMinTextSize="5sp"
app:autoSizeStepGranularity="1sp"/>
Which value did you set to android:layout_height attribute ?
From the document: "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."
I also created a tutorial about Autosizing TextView here.
In my case something very stupid was the issue: While autosizing always worked fine for me, on exactly one TextView I used the android: namespace instead of app:! I was totally oblivious to my mistake and kept wondering why it didn't work. So when using an AppCompat theme always make sure to use the AppCompat attributes, not the native ones.
Additional info to #Sira Lam 's accepted answer:
Always make sure you don't inherit attributes that might conflict AutoTextSize's behavior, particularly android:singleLine.
Even though android:maxLines or android:lines do not obstruct the TextView from sizing accordingly, the singleLine attribute (when set to true) completely disables any auto sizing.
So, when tracking down an AutoTextSize issue, first try searching for the singleLine attribute, as it is sometimes inherited when extending Button.
Make sure to check these options in order to autoSize work:
Don't use wrap_content in any dimensions (such as layout_width and layout_height)
Make sure to not use singleLine, instead use android:maxLines
Use app:autosizexxx instead of android:autosizexxx in order to support older android versions
Autosize works in both AppCompatTextView and TextView, so you don't need to change your View
Have you tried setting all of the four attributes described in the link you posted?
E.g.
app:autoSizeTextType="uniform"
app:autoSizeMaxTextSize="13sp"
app:autoSizeMinTextSize="5sp"
app:autoSizeStepGranularity="1sp"
You can also try setting both width and height to wrap_content, and setting minWidth and maxWidth to 56dp.
As poss also mentioned in the comments, maxlines seems to cause problems (for me as well), so try removing that (The autosizing should probably take care of this, by reducing the textsize).
Config your TextView like 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"
/>
Work well on Android 22, 23, 26
Beside autosize attributes for single line TextView I had to add textSize too, so the height which was wrap, was big enough to let the text resize to it's maximum size defined
android:lines="1"
android:maxLines="1"
android:textSize="30sp"
app:autoSizeMaxTextSize="30sp"
app:autoSizeMinTextSize="12sp"
app:autoSizeTextType="uniform"
if you do not know size of textview. e.g. you put them in linearlayout and set height or width to 0dp. then I got a solution. you need to setAutoSizeTextTypeWithDefaults in OnSizeChanged event.
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.setAutoSizeTextTypeWithDefaults(AUTO_SIZE_TEXT_TYPE_UNIFORM);
}
Makesure use android:maxLines=1 as #Henning said.
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#color/white"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
app:autoSizeMaxTextSize="16sp"
app:autoSizeMinTextSize="12sp"
app:autoSizeTextType="uniform"
tools:text="Downloading" />
Related
So I have two text views, one a that has a specific height and auto-size properties implemented in it. The other is a normal multiple lined text view with wrap content as height.
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvMovieRating"
android:layout_width="match_parent"
android:layout_height="#dimen/tvOthersActivityMovieHeight"
android:layout_marginStart="#dimen/text_view_movie_description_margin_start"
android:layout_marginHorizontal="#dimen/mainCLMarginActivityMovie"
android:text="#string/movieRatingHint"
android:textColor="#color/white"
app:autoSizeMaxTextSize="#dimen/all_auto_max_text_sizes"
app:autoSizeMinTextSize="#dimen/all_auto_min_text_sizes"
app:autoSizeStepGranularity="#dimen/all_auto_size_step_granularities"
app:autoSizeTextType="uniform"
app:layout_constraintTop_toBottomOf="#id/tvMovieNameAndDate"
/>
<TextView
android:id="#+id/tvMovieDescriptionList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/text_view_movie_description_margin_start"
android:layout_marginHorizontal="#dimen/mainCLMarginActivityMovie"
android:textSize="268sp"
android:text="#string/lorem_ispum"
android:textColor="#color/white"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tvNonChangeableDescriptionText"
/>
Now what I'm trying to set the 2nd textView's textSize size based on the first textView's textSize.
I've tried:
binding.tvMovieDescriptionList.textSize = binding.tvMovieRating.textSize
but it didn't work, any help?
You cannot directly do the following: setTextSize(getTextSize()).
The reason is the getTextSize() is returning the exact pixel size, meanwhile setTextSize() sets the scaled pixel unit. The unit does not align with these functions.
So for the simplest way, you can mention the unit when you are setting the size:
binding.tvMovieDescriptionList.setTextSize(TypedValue.COMPLEX_UNIT_PX, binding.tvMovieRating.textSize)
Or you can calculate the scaled pixel unit yourself before setting:
val metrics = resources.displayMetrics
binding.tvMovieDescriptionList.textSize = binding.tvMovieRating.textSize / metrics.density
Perhaps you've forgotten to notify your binding. Most changes in bindings require you to notify them to update them. I would try
binding.notify()
or
binding.notifyAll()
On another note, you could always simply copy your auto-sizing dimensions over to your secondary text view. I don't see why you couldn't do that, as this is only two text views, not 1120.
I have the following TextView:
<com.mycompany.CustomTextView
android:id="#+id/productName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="3"
android:maxLines="3" />
This results in an expected look of the TextView with different amounts of text:
However, when I use our corporate font created by our company, the TextView is getting bigger with every line with no text:
I don't know how this can be dependent on the used font. Is there any attribute in the .ttf file that leads to this odd behaviour?
My first thought was that Android adds new paragraphs to the TextView if not all of the lines are filled. But it would be new to me that a font file can define a default paragraph spacing.
As your view has height and width as "wrap_content" with max_lines = 3. Now it's quite obvious that view's dimensions will change depending as it will figure it out that how much height it will need to accommodate three lines of specific type (font) of input text
As you have custom Textview.Calculate and update LayoutParams dynamically based on the aggregate height of each line.
Yes Text size will vary based on font types.
Check this for detail explanation.
Vote if it helps.
Thanks. Happy coding.
Is there's way to change the text size to fit screen-width ?
i have Header with long title, the problem is on small size screen that title goes to another line. i would like to change font size to fit the whole text in 1 line
Android officialy supports autosizing.for implementing dynamic size you should set autoSizeTextType attribute to uniform and set autoSizeMaxTextSize and autoSizeMinTextSize attributes to your desired size.
*attention : for apis below 26 you should use 'app' prefix for attributes instead of 'android' .
and finally you should have a textView like this for stretching text to screen-width:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="Hello, how are you today"
android:textSize="100sp"
app:autoSizeMaxTextSize="100sp"
app:autoSizeMinTextSize="12sp"
app:autoSizeStepGranularity="2sp"
app:autoSizeTextType="uniform"
/>
TextViewCompat from AndroidX is the official solution for your problem.
I wanted to know if it was possible to create a custom TextView that centers text perfectly, no matter what the font is. That's my major issue right now, but I'm also wondering if it's possible to set the specific height using pixels so that the height would also be consistent.
This picture shows how different fonts are sized and centered. The longest black line in the picture is the middle of the white space. Letters in the picture are the same in every way except for the fonts. The text size is the same (text.setTextSize(TypedValue.COMPLEX_UNIT_PX, 450);), and they're all centered. I hope someone knows the answer to these questions! If you need any code from my app, just ask. Thanks!
EDIT: I am aware of android:gravity="veritcal_center", but that only works to an extent. What you see above is that implemented in the textview, but each font has a different center of gravity, so android:gravity="veritcal_center" wouldn't really make all of these center perfectly along the screen. I'm looking for a way to create a custom textView that somehow measures the height of text and centers it with those parameters. A suggestion by #vmironov in the comments works, but only if the textview has one character. I have not been able to mess around with his code, but I will when I get a chance and I'll post here if I find anything. Thanks!
A simple way to achieve what you want is to use following code:
<LinearLayout
android:layout_width="100dp"
android:layout_height="20dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="#string/your_text" />
</LinearLayout>
set the height and width values of LinearLayout fixed if you want to set the text to be alligned in center within constant height and width
Set the gravity of the view to "center_vertical". Something like :
android:gravity="center_vertical"
You should be able to center your text by applying a gravity attribute to the containing TextView.
In XML you would assign an attribute to your TextView, which would look like this:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/some_text" />
If you do want to specify a particular size for your text, it is strongly suggested you use SP (Scaled Pixels) as your unit of measurement, and not Pixels. You could also set an Appearance Attribute for your TextView to control the size, which is also shown in the code example.
I have a few TextViews in my app where I use a custom typeface. I have given the view centered layout gravity to get the text centered in its parent layout. It looks fine in the previewer with the Sans font, but when I change the typeface, the result looks like the text is shifted down, like this:
Compared to this:
Here is the xml for that element:
<FrameLayout android:id="#+id/Turn_ScoreA_Frame" android:padding="5dp" android:background="#color/teamA_secondary" android:layout_margin="5dp" android:layout_gravity="center" android:layout_height="50dp" android:layout_width="110dp">
<android.view.View android:id="#+id/Turn_ScoreABG" android:background="#color/teamA_primary" android:layout_height="fill_parent" android:layout_width="fill_parent"></android.view.View>
<TextView android:id="#+id/Turn_ScoreA" android:includeFontPadding="false" android:text="5" android:layout_gravity="center" android:layout_height="wrap_content" android:layout_width="wrap_content" android:textSize="32dp"></TextView>
</FrameLayout>
This also occurs when I use fill_parent for layout_width and height of the text view, with text gravity center. I set the custom Typeface in the OnCreate of the view in which this layout is used, just by using TextView.SetTypeface.
Does anyone know what could be causing this? I'm having trouble tracking anything down on this.
As a note, I've worked around this on several views by setting the margin_bottom to -10dp or so, but I'd like to remove that, and I can't get that hack to work on confined views like this one, anyways.
The font is Anton, by the way.
EDIT: This is definitely the result of the text being too large for its container. The thing is, Sans fits just fine, and the new font would fit but its measured size is too large. What I'm hoping is to find a way to get the text to remain at its current visible size and fit in the center of the container, in such a way that doesn't feel too hacky =)
You need to add:
android:includeFontPadding="false"
You have 3 options
Decrease the text size
Increase the height of FrameLayout
Change the font which can fit correctly
you cannot change the property of the font, it is designed is such a way that it has empty space above it, which doesn't fit in your given android:layout_height="50dp" when android:textSize="32dp"