最近项目有个需求要求文本最多显示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; } }