androiddeveloperlb / autofittextview Goto Github PK
View Code? Open in Web Editor NEWA TextView that automatically fit its font and line count based on its available size and content
License: Apache License 2.0
A TextView that automatically fit its font and line count based on its available size and content
License: Apache License 2.0
I added
android:maxLines="5"
android:ellipsize="end"
to put an ellipsis when the text reaches more than 5 lines, but it simply doesn't work or sometimes ellipsis is not in the right place (in the middle of the sentence)
I am using this library in my project. But library is not working if string has only emojis.
"message":"ππ"
See 1 user send only emojis. and app crashed in production version. Android 10
JAVA FILE
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//auto resizing fails on the first run
show_auto_resized_text();
//but when we use user touch it works
TextView button=(TextView) findViewById(R.id.text_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
show_auto_resized_text();
}
});
}
public void show_auto_resized_text(){
FrameLayout text_container=(FrameLayout) findViewById(R.id.container);
text_container.removeAllViews();
int width= text_container.getWidth()-40;
int height= text_container.getHeight()-40;
AutoResizeTextView textView=new AutoResizeTextView(MainActivity.this);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
textView.setMaxLines(10);
textView.setTextColor(Color.WHITE);
textView.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, height, getResources().getDisplayMetrics()));
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
final String DOUBLE_BYTE_SPACE = "\u3000";
String fixString = "";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR1
&& android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
fixString = DOUBLE_BYTE_SPACE;
}
textView.setText(fixString + "THIS IS MY TEXT TO BE AUTO RESIZED" + fixString);
text_container.addView(textView);
}
}
XML FILE
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.kr.hakan.myapplication.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_above="@+id/text_button"
android:background="#ff5b14"
android:layout_margin="20dp"
android:id="@+id/container"></FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Auto Resize The Text"
android:id="@+id/text_button"
android:layout_alignParentBottom="true"
android:background="#000000"
android:textSize="30sp"
android:textColor="#ffffff"
android:gravity="center" />
</RelativeLayout>
Since android support Letter Spacing from api 21, I needed to implement custom logic for that. I used stackoverflow solution. After applying LetterSpacing text is too small.
Layout of custom view for Tab:
<AutoResizeTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:textSize="18sp"
android:textStyle="bold"/>
Code for setting up TabLayout in Activity:
_tabLayout.setupWithViewPager(_viewPager);
_tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
_tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(_viewPager)
{
@Override
public void onTabSelected(TabLayout.Tab tab)
{
_viewPager.setCurrentItem(tab.getPosition(), true);
ViewHolder viewHolder = (ViewHolder) tab.getTag();
viewHolder.TabTitleView.setTextColor(getResources().getColor(R.color.primaryColor));
viewHolder.TabTitleView.setText(_pageAdapter.getPage(tab.getPosition()).getSelectedTitle());
}
@Override
public void onTabUnselected(TabLayout.Tab tab)
{
ViewHolder viewHolder = (ViewHolder) tab.getTag();
viewHolder.TabTitleView.setTextColor(getResources().getColor(R.color.tab_title_color));
viewHolder.TabTitleView.setText(_pageAdapter.getPage(tab.getPosition()).getTitle());
}
});
for(int i = 0; i < _pageAdapter.getCount(); i++)
{
TabLayout.Tab tab = _tabLayout.getTabAt(i);
tab.setCustomView(R.layout.tab_title);
ViewHolder viewHolder = new ViewHolder(tab.getCustomView(), _tabLayout.getContext());
viewHolder.TabTitleView.setText(_pageAdapter.getPage(i).getTitle());
tab.setTag(viewHolder);
if(i == 0)
viewHolder.TabTitleView.setTextColor(getResources().getColor(R.color.primaryColor));
}
Hi,
I trie to add it in the home widget but I always get Problem loading widget and the widget does not get displayed.
Any ideas how to solve this problem?
When using the AutoResizeTextView inside a Listview adapter that implements correctly the corvertview
, textsize
goes decreasing more and more until it reaches the minimal size.
Is there a way to reset the default value?
Already tried:
textview.reAdjust();
and also
textview.setTextSize(TypedValue.COMPLEX_UNIT_SP, 28);
without success
I have a layout that has two columns, they are defined as LinearLayout, see code below. I think AutoFixTextView does not take into account the size of the LinearLayout it is contained in, but one level up. This results in the word being truncated, see the attached screen-shot (it should end with PNG).
<?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"
android:layout_gravity="center_vertical"
android:background="@drawable/my_background_border"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:background="@drawable/my_background_border"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/my_background_border"
>
<android.support.design.widget.FloatingActionButton
android:id="@+id/previous_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:src="@drawable/navigate_previous" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/next_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:src="@drawable/navigate_next" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/card_text_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:background="@drawable/my_background_border"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/my_background_border"
>
<com.thedatawise.www.toddlerflip.AutoResizeTextView
android:id="@+id/card_back_text"
android:textColor="#000"
android:textAllCaps="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:textSize="100sp"
android:text="BACK PAGE" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Hi, i'm using your library that i found very usefull. But i've some problem with it. I'm making a back and forth between two activites and every time i came back on the first one the text is getting smaller and smaller and smaller again. Is it possible to stop this?? and with big text size like 150sp is it possible to erase the font padding top and bottom??
PS: I think import android.annotation.TargetApi is deprecated
It seems that this TextView doesn't run well in Android 5.0+,How to fix it ?Thank you!
Hi you made an amazing solution for the auto fit textview. It's really awesome. Today i am trying to apply this class on my sample project. It almost work perfectly on all android version except one version (it is Lollipop ). text is not display on the screen for the lollipop version. I don't know why !!!
I check there is no mistake in my sample code.
Thanks for this superb class +1
Hello,
Thanks for great library, but can you please suggest how to use this if it has weblinks? ("Go checkout my website http://google.com")
If no weblink, it working awesome.
Thanks!
Hi!,
I've a recyclerView with a lot of cardView. Each cardView has an autoResizeTextView and when I scroll fastly (down & up) the autoResizeTextView gets crazy... too much little in the most of time.
How Can I resolve this?
thanks in advance!
Not sure when this happens, but maybe it's because I use Html.fromHtml for the text in the textView, and font-family .
On 5.1.1 with a note 5. When an AutoResizeTextView is bound through data binding, the layout crashes with an "IllegalArgumentException: Layout: -140 < 0". The textview is bound to an object with an empty value for the field.
This happens after onTestSize is called, AutoResizeTextView.java line 192 is called.
testing on android lollipop on a nexus 5, the text seems to be smaller than it could be.
I tried adjusting getLineWidth
to getLineRight
and got a result that seems to work. any idea of the difference between these two APIs?
The link you provided for EditText on the main page is dead :-(
Do you have a new link? I need this on a EditText...
Repo ->
For a quick how to:
# add submodule to track master branch
git submodule add -b master [URL to Git repo];
# update your submodule
git submodule update --remote
so it goes like this:
git submodule add https://github.com/CrandellWS/AutoFitEditTextLib
git submodule update --remote
See What you can do...But basically I need to use both libs because yours is TextView and the other is EditText.
Hi,
I need to add a shadow behind the textview. The shadow has a quite large radius, so that it with my current solution will be clipped in many instances as the bounding box isn't increased when I add the shadow.
If this was a normal TextView I could just add some padding to it to avoid the clipping, however when I do that now the text becomes smaller. I would like to avoid that.
Anyone have any thoughts on how I should add padding without making the text smaller?
Thanks in advance!
Can you add a auto resize helper for widget TextView?
Please create dependencies compile 'your.library'
Do we really need to calculate maxWidth based on layout.getLineWidth(i)?
I changed the code just to
textRect.right = _widthLimit;
end everything works fine.
In fact I had an issue when the font size selected was too small when calculated value for maxWidth was > _widthLimit (btw if I calculate maxWidth based on layout.getLineMax(i) I get a value <= _widthLimit).
Anyway thanks for great lib :)
hey guy, what's up?
i have problem, when i add android:onclick="..." attr in AutoResizeTextView and after the run it, when i click on the AutoResizeTextView ,application crashes and force close!
but when I change the AutoResizeTextView to TextView, the problem is fixed
i think this is a bug and should be fix it to make better library
i am getting
java.lang.StringIndexOutOfBoundsException: length=379; index=379
at java.lang.String.charAt(Native Method)
at com.lb.auto_fit_textview.AutoResizeTextView$1.onTestSize(AutoResizeTextView.java:89)
at com.lb.auto_fit_textview.AutoResizeTextView.binarySearch(AutoResizeTextView.java:227)
at com.lb.auto_fit_textview.AutoResizeTextView.superSetTextSize(AutoResizeTextView.java:219)
at com.lb.auto_fit_textview.AutoResizeTextView.adjustTextSize(AutoResizeTextView.java:213)
at com.lb.auto_fit_textview.AutoResizeTextView.onSizeChanged(AutoResizeTextView.java:251)
Can you provide a sample activity that is very simple:
Thanks.
Hello, please remove allowBackup tag from library manifest, it can cause manifest merge error. However library should not care about backup at all.
Thanks.
My implementation is the next one:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_centerVertical="true"
android:orientation="vertical"
android:layout_toLeftOf="@id/layout_right">
<com.bla.customautoresize.AutoResizeTextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test item"
yuilop:maxTextSize="36sp"
yuilop:minTextSize="14sp"
android:textSize="36sp"
android:autoLink="all"
android:maxLines="1"
/>
<com.bla.customautoresize.AutoResizeTextView
android:id="@+id/item_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test description"
yuilop:maxTextSize="36sp"
yuilop:minTextSize="14sp"
android:textColor="#ff606060"
android:autoLink="all"
android:visibility="gone"/>
</LinearLayout>
((TextView)itemModel.findViewById(R.id.item_price)).setText(details.getPrice());
I've played a bit with minTextSize and textSize values but apparently doesn't affect to the result :-S.
I'm testing it on a Nexus 5 with Android L ( API 20 )
In order to be a correct license, you'd need to a dd a copyright statement, like:
Copyright 2020 Me Person
I am using AutoResizeTextView
in FrameLayout
and I am setting custom typeface.
There is space at the end of AutoResizeTextView
[similar to what bottomPadding would produce].
When I don't set Typeface
, it works fine.
I think the issue is, AutoResizeTextView
is not considering the new Typeface
in calculation, As the height of AutoResizeTextView
remains same[as when system default typeface is used] when using non-default typeface, and the difference shows up as a gap, I am sure, if my default and non default typeface would be switched, then the text shown will be truncated, due to insufficient space.[I have not tested this]
not supporting all typefaces
Hello. I found out that when trying to load a String that ends with newline, AutoFitTextView crashes the app with a StringIndexOutOfBoundsException. This does not always happen, but I am able to reproduce this bug with the following string:
String test = "(WLAN)\n";
myAutoFitTextView.setText(test);
My app crashes when the settext is excecuted. Thanks for this library, it's really needed on the Android platform.
The full stacktrace follows:
java.lang.StringIndexOutOfBoundsException: length=7; index=7
at java.lang.String.indexAndLength(String.java:500)
at java.lang.String.charAt(String.java:494)
at com.lb.auto_fit_textview.AutoResizeTextView$1.onTestSize(AutoResizeTextView.java:89)
at com.lb.auto_fit_textview.AutoResizeTextView.binarySearch(AutoResizeTextView.java:227)
at com.lb.auto_fit_textview.AutoResizeTextView.superSetTextSize(AutoResizeTextView.java:219)
at com.lb.auto_fit_textview.AutoResizeTextView.adjustTextSize(AutoResizeTextView.java:213)
at com.lb.auto_fit_textview.AutoResizeTextView.onSizeChanged(AutoResizeTextView.java:251)
at android.view.View.sizeChange(View.java:15804)
at android.view.View.setFrame(View.java:15769)
at android.widget.TextView.setFrame(TextView.java:4661)
at android.view.View.layout(View.java:15685)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1091)
at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:801)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:815)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15689)
at android.view.ViewGroup.layout(ViewGroup.java:5040)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2116)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1873)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1084)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5990)
at android.view.Choreographer$CallbackRecord.run(Choreographer
In my app I have sentence with full screen width on a welcome screen.
When text is in a Hebrew language the words are cut in the bottom of last line.
Adding bottom padding or setting clipToPadding/clipChildren don't help.
Can't use the Google autosizing TextView because it still has a "breaking the words issue".
The code generally works great, but it's important to know that when used inside a ViewPager, the sliding gesture may not work unless special precautions are taken. The problem is that by default, singleLine is set to true and that also causes scrollHorizontally to be set to true. So in order to work around this, make sure in your XML layout you control the line count with maxLines and not singleLine property:
android:maxLines="1"
android:singleLine="false"
I'm trying to change the textSize programmatically according to the string length, but I don't see changes.
if(getItem( position ).getValue().length()<12){
textView.setTextSize(18);
}
else{
if(getItem( position ).getValue().length()>11&&getItem( position ).getValue().length()<25){
textView.setTextSize(15);
}
else{
textView.setTextSize(13);
}
}
textView.setText( getItem( position ).getValue() );
if(selectedItem==position){
textView.setTypeface(selected);
textView.setTextColor(context.getResources().getColor(R.color.white));
}
else{
textView.setTypeface(unselected);
textView.setTextColor(context.getResources().getColor(R.color.black));
}
The typeface is being changed properly, but not the textSize (and there are a lot of different string sizes).
Thanks in advance.
I have found a bug, when it is all Chinese sentence and more then one line, the textsize would be divided to min size.
It is because:
https://github.com/AndroidDeveloperLB/AutoFitTextView/blob/master/AutoFitTextViewLibrary/src/com/lb/auto_fit_textview/AutoResizeTextView.java#L89
in Chinese sentence, words was not linked by
or -
so the method isValidWordWrap
return false everytime in Chinese sentence, and then the sizebecome smaller and smaller(οΌβ²β`)
In the core of the comparison a float is cast to an int:
for(int i=0;i<layout.getLineCount();i++)
if(maxWidth<layout.getLineWidth(i))
maxWidth=(int)layout.getLineWidth(i);
textRect.right=maxWidth;
This cast underestimates the width of the line and so may allow a font size to pass as small enough. The correct solution would be to round up the float I think. What do you think?
I use AutoResizeTextView and set the string in strings.xml such as "This is a string\nwith new line character". The string will displayed as a very small text.
I think the issue is in isValidWordWrap method, it doesn't include (before == '\n') as a valid word wrap. I have tested by adding (before == '\n') in isValidWordWrap method as following:
public boolean isValidWordWrap(char before, char after) {
return before == ' ' || before == '-' || before == '\n';
}
And it will work as expected.
Hi! Please can you clarify the usage of setTextSize
method in the sample project here. I just can't wrap my head around it. What I need is to auto size a text font in accordance with the given width and height bounds. But according to the sample the text size should be set beforehand.
So how can I determine the initial text size to make the autosizing work? Thanks in advance.
Could you upload this to maven central for easy including into project
The problems caused by this() are most evident when changing the base class from TextView to it's close relative EditText. The EditText behaves rather oddly because it's never gets set up with some important default internal styles (see Android source for EditText(Context, AttributeSet)).
Your current code has the two simpler constructors calling the 3-argument constructor via 'this(context, attrs, 0)'. The derived constructors should be calling super(), not this() and also calling a common init() method which contains the autofit init code.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.