最近項目有個需求要求文本最多顯示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; } }