Android TextView,EditText要求固定行数自动调整TextSize

最近项目有个需求要求文本最多显示3行,继续输入则字体变小,删除已经输入的文字,那么字体变大,不管变大变小都不能超过3行。网上怎么找也找不到相关的解决方案,自己动手,丰衣足食了!

说一下算法思路,后面给出demo。

 第一步 获取当前的行数

    我们需要知道目前文本多少行了,之前我采用TextView.getPaint().measureText("your text")这种方法来获取文字的总长度,然后再除以每行的宽度,得到行数,其实这个算法也是可行,不过我采用更简单的方法了。采用view.post方法里面可以通过lineCount = textView.getLineCount();获取正确的行数,否则getLineCount()一直等于0。

   第二步 训练小于多少个字数的时候使用多大的字体

    比如0~30个字数的时候,字体大小是50sp不会超过3行,31~50个字数的时候,字体大小是40sp不会超过3行,51~80个字数的时候,字体大小是30sp不会超过3行。那么这个数据需要记录,因为,删除文字的时候,删到哪个位置需要知道改用多大的字体。而且取得当前当前位置使用多大的字体的时候,需要删除这个字数和字体大小对应关系的数据,因为,这个数据,我们需要不断的训练更新,因为大小写,字符,不同的语言,得到到文字length是不同的。

   有了上面两步的分析,我们就可以动态的调整文字的TextSize了。

   给出完整的Demo

   1、页面设计,简单的就一个输入框和一个文本框,输入框输入上面文本框就显示什么

<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.figo.study.activity.TextActivity">

    <TextView
        android:id="@+id/txt_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/et_msg"
        android:text="@string/hello_world"
        android:textColor="#ffffff" />

    <EditText
        android:id="@+id/et_msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="141dp" />

</RelativeLayout>

 2、Activity编写

package com.figo.study.activity;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import com.figo.study.R;
import com.figo.study.utils.CommonUtil;
import java.util.ArrayList;

/**
 * 控制在3行,自动调整textSize
 */
public class TextActivity extends Activity {
    TextView mTxt;
    EditText mEt;
    int mDefaultTextSize = 50;
    int lineCount = 0;
    int lastTextLength = 0;
    boolean isMinus = false;
    int maxTextSize = 50;
    int minTextSize = 6;
    ArrayList<PositionTextSize> arrayListPts = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text);
        initView();
    }

    private void initView() {
        mTxt = (TextView) findViewById(R.id.txt_msg);
        mTxt.setMaxWidth(600);
        mTxt.setTextSize(mDefaultTextSize);
        mEt = (EditText) findViewById(R.id.et_msg);
        mEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                mTxt.setText(s.toString());
                resizeTextSize(mTxt);
            }
        });
    }


    private void resizeTextSize(final TextView textView) {
        textView.post(new Runnable() {
            @Override
            public void run() {
                TextPaint textPaint = textView.getPaint();
                float currentTextSize = CommonUtil.px2sp(TextActivity.this, textPaint.getTextSize());
                float newTextSize = currentTextSize;

                lineCount = textView.getLineCount();
                int currentTextLength = textView.getText().length();
                if (currentTextLength > lastTextLength) {
                    isMinus = false;
                } else {
                    //说明是在减
                    isMinus = true;
                }
                lastTextLength = currentTextLength;

                if (lineCount > 3) {
                    if (currentTextSize > minTextSize) {
                        newTextSize = currentTextSize - 10;
                    }
                    PositionTextSize pts = new PositionTextSize();
                    pts.textSize = currentTextSize;
                    pts.position = currentTextLength;
                    arrayListPts.add(pts);

                }
                if (isMinus) {
                    newTextSize = findPositionTextSize(currentTextLength);
                }
                if ((newTextSize != currentTextSize) && newTextSize > 0) {
                    textView.setTextSize(newTextSize);
                }
                Log.i("TextActivity", "getLineCount:" + lineCount);
                Log.i("TextActivity", "textSize:" + currentTextSize);
                Log.i("TextActivity", "textLength:" + currentTextLength);
                Log.i("TextActivity", "ArraryTextSize:" + arrayToString(arrayListPts));
            }

        });
    }

    private String arrayToString(ArrayList<PositionTextSize> arrPts) {
        StringBuffer buffer = new StringBuffer();
        for (PositionTextSize pts : arrPts) {
            buffer.append("position:" + pts.position);
            buffer.append(",textSize:" + pts.textSize + "|");
        }
        return buffer.toString();
    }

    private float findPositionTextSize(int position) {
        float textSize = 0;
        PositionTextSize result = null;
        int size = arrayListPts.size();
        for (int p = size - 1; p >= 0; p--) {
            if (arrayListPts.get(p).position > position) {
                result = arrayListPts.get(p);
                textSize = result.textSize;
                arrayListPts.remove(result);//删除重新训练
            }
        }
        return textSize;
    }

    public class PositionTextSize {
        int position;
        float textSize;
    }
}
原文地址:https://www.cnblogs.com/zhujiabin/p/5917206.html