Java 调整文本大小以适应Android中的按钮

Java 调整文本大小以适应Android中的按钮,java,android,button,settext,adjustment,Java,Android,Button,Settext,Adjustment,我在线性布局中有许多按钮。 按钮有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;

我在线性布局中有许多按钮。 按钮有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);
}
for(int i=0;i
如何检查按钮中是否有文本

关键是用文本填充所有按钮,这样文本就占据了所有可用空间,既不会被截断,也不会被拆分成行

例如。
String[]text=新字符串[]{“0”,“sin^-1”}

如果我为“0”选择一个文本大小来占据整个空间,那么我会将“sin”分成两行,“sin^”和“-1”或“0”看起来比它应该的小。

我编辑了@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();
}
}
导入android.content.Context;
导入android.content.res.TypedArray;
导入android.util.AttributeSet;
导入android.util.TypedValue;
公共类FontFitTextView扩展了android.support.v7.widget.AppCompatButton
{
专用静态最终浮动阈值=0.5f;
私有枚举模式{Width,Height,Both,None}
私有int minTextSize=1;
私有int maxTextSize=50;
私有模式=模式。无;
私有布尔不计算;
私人的,私人的;
私人内部高度测量;
公共FontFitTextView(上下文){
超级(上下文);
}
公共FontFitTextView(上下文、属性集属性){
这(上下文,属性,0);
}
公共FontFitTextView(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
TypedArray tAttrs=context.ActainStyledAttributes(attrs,R.styleable.fontfittTextView,defStyle,0);
maxTextSize=tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView\u maxTextSize,maxTextSize);
minTextSize=tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView\u minTextSize,minTextSize);
tAttrs.recycle();
}
私有void resizeText(){
如果(getWidth()=targetWidth | | getMeasuredHeight()>=targetHeight;
if(mode==mode.Width)
返回getMeasuredWidth()>=targetWidth;
其他的
返回getMeasuredHeight()>=targetHeight;
}
私有模式getMode(int-widthMeasureSpec,int-heightMeasureSpec){
int widthMode=MeasureSpec.getMode(widthmasurespec);
int heightMode=MeasureSpec.getMode(heightMeasureSpec);
if(widthMode==MeasureSpec.justice&&heightMode==MeasureSpec.justice)
返回模式;
if(widthMode==MeasureSpec.justice)
返回模式。宽度;
if(heightMode==MeasureSpec.justice)
返回模式。高度;
返回模式。无;
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
超级测量(宽度测量、高度测量);
if(!不计算){
this.widthMeasureSpec=widthMeasureSpec;
this.heightmeasurept=heightmeasurept;
模式=getMode(宽度测量等级、高度测量等级);
resizeText();
}
}
受保护的void onTextChanged(最终字符序列文本、最终整数开始、最终整数之前、最终整数之后){
resizeText();
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
如果(w!=oldw | | h!=oldh)
resizeText();
}
public int getMinTextSize(){
返回最小文本大小;
}
public void setMinTextSize(int minTextSize){
this.minTextSize=minTextSize;
resizeText();
}
public int getMaxTextSize(){
返回maxTextSize;
}
公共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标记而不是按钮:

<com.example.myname.testsidebar.FontFitTextView
            android:id="@+id/userDetailsBtn"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            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"/>


希望能有所帮助。

试试看。这确实有效,但它会创建文本视图。现在我需要将这些文本视图转换为按钮。这并不是我所需要的。它不会更改文本大小以使文本适合视图。它会更改视图的大小。最后,所有文本都适合视图,但视图大小不同。