Skip to content

Commit f1b634c

Browse files
committed
pulling custom view out so easy to find in project
1 parent 4dc30e8 commit f1b634c

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed

SizeAdjustingTextView.java

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
2+
import android.content.Context;
3+
import android.text.Layout.Alignment;
4+
import android.text.StaticLayout;
5+
import android.text.TextPaint;
6+
import android.util.AttributeSet;
7+
import android.util.TypedValue;
8+
import android.widget.TextView;
9+
10+
/**
11+
*
12+
* SizeAdjustingTextView is a TextView that adjusts text size
13+
* depending if or if not it will fit in the view bounds.
14+
* Copyright (C) 2014 Elliott Chenger
15+
*
16+
* This program is free software; you can redistribute it and/or
17+
* modify it under the terms of the GNU General Public License
18+
* as published by the Free Software Foundation; either version 2
19+
* of the License, or (at your option) any later version.
20+
*
21+
* This program is distributed in the hope that it will be useful,
22+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24+
* GNU General Public License for more details.
25+
*
26+
* You should have received a copy of the GNU General Public License
27+
* along with this program; if not, write to the Free Software
28+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29+
*
30+
* @author Elliott Chenger
31+
* @since Jan 18, 2014
32+
* @author Chase Colburn
33+
* @since Apr 4, 2011
34+
*
35+
*/
36+
public class SizeAdjustingTextView extends TextView{
37+
38+
// Minimum text size for this text view
39+
public static final float MIN_TEXT_SIZE = 20;
40+
41+
// Our ellipse string
42+
private static final String mEllipsis = "...";
43+
44+
// Flag for text and/or size changes to force a resize
45+
private boolean mNeedsResize = false;
46+
47+
// Text size that is set from code. This acts as a starting point for resizing
48+
private float mTextSize;
49+
50+
// Temporary upper bounds on the starting text size
51+
private float mMaxTextSize = 0;
52+
53+
// Lower bounds for text size
54+
private float mMinTextSize = MIN_TEXT_SIZE;
55+
56+
// Text view line spacing multiplier
57+
private float mSpacingMult = 1.0f;
58+
59+
// Text view additional line spacing
60+
private float mSpacingAdd = 0.0f;
61+
62+
// Add ellipsis to text that overflows at the smallest text size
63+
private boolean mAddEllipsis = true;
64+
65+
// Default constructor override
66+
public SizeAdjustingTextView(Context context) {
67+
this(context, null);
68+
}
69+
70+
// Default constructor when inflating from XML file
71+
public SizeAdjustingTextView(Context context, AttributeSet attrs) {
72+
this(context, attrs, 0);
73+
}
74+
75+
// Default constructor override
76+
public SizeAdjustingTextView(Context context, AttributeSet attrs, int defStyle) {
77+
super(context, attrs, defStyle);
78+
mTextSize = getTextSize();
79+
}
80+
81+
@Override
82+
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
83+
mNeedsResize = true;
84+
// Since this view may be reused, it is good to reset the text size
85+
resetTextSize();
86+
}
87+
88+
@Override
89+
public void setText(CharSequence text, BufferType type) {
90+
super.setText(text, type);
91+
resizeText();
92+
}
93+
94+
@Override
95+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
96+
if (w != oldw || h != oldh) {
97+
mNeedsResize = true;
98+
}
99+
}
100+
101+
102+
@Override
103+
public void setTextSize(float size) {
104+
super.setTextSize(size);
105+
mTextSize = getTextSize();
106+
}
107+
108+
@Override
109+
public void setTextSize(int unit, float size) {
110+
super.setTextSize(unit, size);
111+
mTextSize = getTextSize();
112+
}
113+
114+
@Override
115+
public void setLineSpacing(float add, float mult) {
116+
super.setLineSpacing(add, mult);
117+
mSpacingMult = mult;
118+
mSpacingAdd = add;
119+
}
120+
121+
public void setMaxTextSize(float maxTextSize) {
122+
mMaxTextSize = maxTextSize;
123+
requestLayout();
124+
invalidate();
125+
}
126+
127+
public float getMaxTextSize() {
128+
return mMaxTextSize;
129+
}
130+
131+
public void setMinTextSize(float minTextSize) {
132+
mMinTextSize = minTextSize;
133+
requestLayout();
134+
invalidate();
135+
}
136+
137+
public float getMinTextSize() {
138+
return mMinTextSize;
139+
}
140+
141+
public void setAddEllipsis(boolean addEllipsis) {
142+
mAddEllipsis = addEllipsis;
143+
}
144+
145+
public boolean getAddEllipsis() {
146+
return mAddEllipsis;
147+
}
148+
149+
public void resetTextSize() {
150+
if(mTextSize > 0) {
151+
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
152+
mMaxTextSize = mTextSize;
153+
}
154+
}
155+
156+
@Override
157+
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
158+
if(changed || mNeedsResize) {
159+
int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
160+
int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
161+
resizeText(widthLimit, heightLimit);
162+
}
163+
super.onLayout(changed, left, top, right, bottom);
164+
}
165+
166+
167+
public void resizeText() {
168+
int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop();
169+
int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
170+
resizeText(widthLimit, heightLimit);
171+
}
172+
173+
public void resizeText(int width, int height) {
174+
CharSequence text = getText();
175+
if(text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
176+
return;
177+
}
178+
float newTextSize = findNewTextSize(width, height, text);
179+
changeTextSize(newTextSize);
180+
mNeedsResize = false;
181+
}
182+
183+
private void changeTextSize(float newTextSize) {
184+
setTextSize(TypedValue.COMPLEX_UNIT_PX,newTextSize);
185+
setLineSpacing(mSpacingAdd, mSpacingMult);
186+
}
187+
188+
private float findNewTextSize(int width, int height, CharSequence text) {
189+
TextPaint textPaint = new TextPaint(getPaint());
190+
191+
float targetTextSize = textPaint.getTextSize();
192+
193+
int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
194+
while(textHeight > height && targetTextSize > mMinTextSize) {
195+
targetTextSize = Math.max(targetTextSize - 1, mMinTextSize);
196+
textHeight = getTextHeight(text, textPaint, width, targetTextSize);
197+
}
198+
return targetTextSize;
199+
}
200+
201+
private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
202+
paint.setTextSize(textSize);
203+
StaticLayout layout = new StaticLayout(source, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
204+
return layout.getHeight();
205+
}
206+
207+
}

0 commit comments

Comments
 (0)