调整文本大小以适应 Android 中的按钮
Posted
技术标签:
【中文标题】调整文本大小以适应 Android 中的按钮【英文标题】:Adjust text size to fit button in Android 【发布时间】:2016-11-24 09:38:19 【问题描述】:LinearLayout 中有许多按钮。 按钮的权重为 1,因此它们被均匀地放置在布局中。 我想做这样的事情
for (int i = 0; i < texts.size(); ++i)
Button button = new Button(/*context*/);
button.setLayoutParams(/*WRAP_CONTENT, MATCH_PARENT, 1.0f*/)
button.setText(texts[i]);
float fontSize = 20.0f;
button.setTextSize();
while (textDoesNotFitIntoButton(button))
fontSize -= 2.0f;
button.setTextSize(fontSize);
linearLayout.addView(button);
如何检查文本是否不适合按钮?
重点是用文本填充所有按钮,使文本占据所有可用空间,既不会被截断,也不会被分割成行。
例如
String[] texts = new String[] "0", "sin^-1" ;
如果我为“0”选择一个单一的文本大小来占据整个空间,那么我要么将“sin”分成两行“sin^”,而“-1”或“0”看起来比它应该的要小。
【问题讨论】:
试试这个***.com/a/5535672/1852441 这确实有效,但它会创建文本视图。现在我需要将这些文本视图变成按钮。 这不是我所需要的。它不会更改文本大小以使文本适合视图。它改变了视图的大小。最后,所有文本都适合视图,但视图大小不同。 【参考方案1】:我已经编辑了@Jaswanth Manigundan 给出的答案,使其扩展自 android.support.v7.widget.AppCompatButton。看看下面的脚本:
FontFitTextView.java
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
public class FontFitTextView extends android.support.v7.widget.AppCompatButton
private static final float THRESHOLD = 0.5f;
private enum Mode Width, Height, Both, None
private int minTextSize = 1;
private int maxTextSize = 50;
private Mode mode = Mode.None;
private boolean inComputation;
private int widthMeasureSpec;
private int heightMeasureSpec;
public FontFitTextView(Context context)
super(context);
public FontFitTextView(Context context, AttributeSet attrs)
this(context, attrs, 0);
public FontFitTextView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
TypedArray tAttrs = context.obtainStyledAttributes(attrs, R.styleable.FontFitTextView, defStyle, 0);
maxTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_maxTextSize, maxTextSize);
minTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_minTextSize, minTextSize);
tAttrs.recycle();
private void resizeText()
if (getWidth() <= 0 || getHeight() <= 0)
return;
if(mode == Mode.None)
return;
final int targetWidth = getWidth();
final int targetHeight = getHeight();
inComputation = true;
float higherSize = maxTextSize;
float lowerSize = minTextSize;
float textSize = getTextSize();
while(higherSize - lowerSize > THRESHOLD)
textSize = (higherSize + lowerSize) / 2;
if (isTooBig(textSize, targetWidth, targetHeight))
higherSize = textSize;
else
lowerSize = textSize;
setTextSize(TypedValue.COMPLEX_UNIT_PX, lowerSize);
measure(widthMeasureSpec, heightMeasureSpec);
inComputation = false;
private boolean isTooBig(float textSize, int targetWidth, int targetHeight)
setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
measure(0, 0);
if(mode == Mode.Both)
return getMeasuredWidth() >= targetWidth || getMeasuredHeight() >= targetHeight;
if(mode == Mode.Width)
return getMeasuredWidth() >= targetWidth;
else
return getMeasuredHeight() >= targetHeight;
private Mode getMode(int widthMeasureSpec, int heightMeasureSpec)
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY)
return Mode.Both;
if(widthMode == MeasureSpec.EXACTLY)
return Mode.Width;
if(heightMode == MeasureSpec.EXACTLY)
return Mode.Height;
return Mode.None;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(!inComputation)
this.widthMeasureSpec = widthMeasureSpec;
this.heightMeasureSpec = heightMeasureSpec;
mode = getMode(widthMeasureSpec, heightMeasureSpec);
resizeText();
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after)
resizeText();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
if (w != oldw || h != oldh)
resizeText();
public int getMinTextSize()
return minTextSize;
public void setMinTextSize(int minTextSize)
this.minTextSize = minTextSize;
resizeText();
public int getMaxTextSize()
return maxTextSize;
public void setMaxTextSize(int maxTextSize)
this.maxTextSize = maxTextSize;
resizeText();
style.xml:
<resources>
<declare-styleable name="FontFitTextView">
<attr name="minTextSize" format="dimension" />
<attr name="maxTextSize" format="dimension" />
</declare-styleable>
</resources>
在我的 activity_main.xml 中,我使用了 FontFitTextView 标签而不是 Button:
<com.example.myname.testsidebar.FontFitTextView
android:id="@+id/userDetailsBtn"
android:layout_
android:layout_
android:drawableTop="@drawable/user_details"
android:gravity="center"
android:background="#00FFFFFF"
android:paddingTop="10sp"
android:textSize="15sp"
android:text="Your Details"
android:drawableTint="#ED1B2F"
android:textColor="#797369"
android:layout_weight="1"
android:layout_gravity="center"/>
希望对你有帮助。
【讨论】:
以上是关于调整文本大小以适应 Android 中的按钮的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React Native for Android 中调整字体大小以适应视图?
Android 自定义TextView实现文本内容自动调整字体大小以适应TextView的大小
如何在 Swift 中以编程方式调整 UIButton 中文本的字体大小以适应宽度?