分析
我们知道AppCompatTextView 中的autoSizeMinTextSize 可以自动字体缩放,但如果在列表中大量使用则会出现性能问题出现卡顿现象。分析AppCompatTextView源码可以看出实现逻辑是通过二分查找找到合适的字体大小,其中多次创建StaticLayout.Builder进行测量。所以在列表中会出现卡顿显现。
简单优化
非常简单的实现,就是 (控件宽度 ➗ 预设字体测试的文本宽度 )X 字号 = 缩放后的字号。
这种方式只适合单行的情况
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.TypedValue;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* 高性能字体缩放TextView控件
* 本控件只支持单行缩放
*
* @author : chengxingyao456@qq.com
* date : 2022/1/17 11:11
*/
public class NatureAutofitTextView extends androidx.appcompat.widget.AppCompatTextView {
private float defaultSize;
private CharSequence oldText;
public NatureAutofitTextView(@NonNull Context context) {
this(context, null, 0);
}
public NatureAutofitTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public NatureAutofitTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setMaxLines(1);
}
@Override
protected void onDraw(Canvas canvas) {
if (!getText().equals(oldText)) {
oldText = getText();
//通过测量默认字体大小文本宽度,与控件宽度进行比例计算,然后与默认字号计算得到缩放后的字体大小
getPaint().setTextSize(defaultSize);
float width = getPaint().measureText(getText().toString());
float scale = (getWidth()-getPaddingLeft()-getPaddingRight()) / width;
if (scale < 1) {
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultSize * scale);
} else {
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultSize);
}
}
super.onDraw(canvas);
}
@Override
public void setTextSize(int unit, float size) {
super.setTextSize(unit, size);
defaultSize = getTextSize();
}}
网友评论