自定义TextView:解决Android字体适配难题
创作时间:
作者:
@小白创作中心
自定义TextView:解决Android字体适配难题
引用
CSDN
等
8
来源
1.
https://blog.csdn.net/u010126792/article/details/89151373
2.
https://blog.csdn.net/qq_35644925/article/details/125222910
3.
https://blog.csdn.net/chuyouyinghe/article/details/125366927
4.
https://www.cnblogs.com/qylost/articles/11430709.html
5.
https://juejin.cn/post/7106714269730914312
6.
https://juejin.cn/post/6991637697924169742
7.
http://leaking.github.io/android/(customView)onMeasure/
8.
https://juejin.cn/post/6844903509901459470
在Android开发中,TextView是最常用的控件之一,用于显示文本信息。然而,在不同设备上,屏幕尺寸和分辨率的差异可能导致TextView的显示效果不尽如人意。本文将详细介绍如何通过自定义TextView来实现字体大小的自动适配,让应用在各种设备上都能保持良好的显示效果。
MeasureSpec原理简介
在深入自定义TextView之前,我们先了解一下MeasureSpec的概念。MeasureSpec是Android系统用来描述View尺寸的机制,它包含了尺寸和模式两部分信息:
- EXACTLY:精确模式,表示父布局已经确定了View的大小,如使用
match_parent
或具体数值。 - AT_MOST:最大值模式,表示View的大小不能超过父布局的限制,如使用
wrap_content
。 - UNSPECIFIED:未指定模式,通常用于系统内部测量。
自定义TextView实现
1. 创建自定义TextView类
我们需要继承View类,并实现基本的构造函数:
public class CustomTextView extends View {
private float textSize;
private String text;
private int textColor;
private Paint textPaint;
private int gravity;
public CustomTextView(Context context) {
super(context);
init();
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 15, getContext().getResources().getDisplayMetrics());
textColor = Color.BLACK;
textPaint = new Paint();
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
gravity = Gravity.CENTER;
}
}
2. 重写onMeasure方法
这是实现自适应的关键步骤。我们需要根据MeasureSpec计算TextView的尺寸:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int w = MeasureSpec.getSize(widthMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
int h = MeasureSpec.getSize(heightMeasureSpec);
int contentWidth = 0;
int contentHeight = 0;
if (text != null && text.length() > 0) {
Rect textSize = measureTextSize();
contentWidth = textSize.width();
contentHeight = textSize.height();
}
if (wMode == MeasureSpec.AT_MOST || wMode == MeasureSpec.UNSPECIFIED) {
w = contentWidth;
}
if (hMode == MeasureSpec.AT_MOST || hMode == MeasureSpec.UNSPECIFIED) {
h = contentHeight;
}
setMeasuredDimension(w, h);
}
private Rect measureTextSize() {
Paint paint = new Paint();
Rect textSize = new Rect();
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), textSize);
return textSize;
}
使用Autosizing方式
Android系统提供了更简便的Autosizing方式,可以在xml中直接配置:
<TextView
android:layout_width="340dp"
android:layout_height="50dp"
android:background="@drawable/shape_bg_008577"
android:gravity="center_vertical"
android:maxLines="1"
android:text="这是标题,该标题的名字比较长,产品要求不换行全部显示出来"
android:textSize="18sp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="18sp"
android:autoSizeMinTextSize="10sp"
android:autoSizeStepGranularity="1sp"/>
或者在Java代码中设置:
TextView tvText = findViewById(R.id.tv_text);
TextViewCompat.setAutoSizeTextTypeWithDefaults(tvText, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM);
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(tvText, 10, 18, 1, TypedValue.COMPLEX_UNIT_SP);
工具类实现非固定宽度适配
对于非固定宽度的适配,我们可以编写一个工具类来动态调整字体大小:
public void adjustTvTextSize(TextView tv, int maxWidth, String text) {
int avaiWidth = maxWidth - tv.getPaddingLeft() - tv.getPaddingRight();
if (avaiWidth <= 0) {
return;
}
TextPaint textPaintClone = new TextPaint(tv.getPaint());
float trySize = textPaintClone.getTextSize();
while (textPaintClone.measureText(text) > avaiWidth && trySize > 8) {
trySize -= 1;
textPaintClone.setTextSize(trySize);
}
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
总结
通过以上三种方式,我们可以灵活应对不同场景下的TextView字体适配问题:
- 自定义View方式适用于需要高度自定义的场景
- Autosizing方式简单易用,适合大多数情况
- 工具类方式则提供了更大的灵活性,特别是在宽度不固定的情况下
开发者可以根据具体需求选择最适合的方案,确保应用在各种设备上都能保持良好的显示效果。
热门推荐
什么是积存金的投资价值?这种投资方式的风险如何控制?
深入了解架构中常见的4种缓存模式及其实现
在运输过程中,如何有效保持沃柑的新鲜度?
在运输过程中,如何有效保持沃柑的新鲜度?
抹茶的健康益处:彻底解释抹茶从美容到预防疾病的功效
探寻李靖:唐朝名将竟成神话界的流量IP
南梁名将陈庆之:文弱之躯铸就一代儒将传奇
你了解等效光圈吗 如何看待全画幅相机与半画幅相机的等效光圈
从被质疑到海外爆火,东海水晶如何利用文化差异赚钱
银行对公业务:供应链金融、现金管理、对公贷款、网银、票据业务
地基高好不好,风水房子地基高好吗
注册深圳南山公司的材料、流程、条件有什么?
交通方便,价格亲民的租房推荐
电力GIS基础知识:从原理到维护的全面解析
什么是猛禽?概念、种类、饮食、特征和例子
鹰、隼、雕、枭的区别是什么?看完涨知识了!建议收藏
2025考研成功必备10个好习惯
千古医圣孙思邈:用一生诠释医者的责任与担当
道医人物 | 药王:孙思邈
燃料电池工作原理:能源新纪元的引擎
男性长期饮酒,身体会有哪些变化?新研究给出答案
房子长期空置不住,要缴纳物业费吗?新规下,很多业主白交不少钱
呼和浩特老牛湾通用机场通过竣工验收,将开通多条短途运输航线
热那亚vs卡利亚里:惊险胜利与战术博弈,热那亚主场首胜可期!
如何根据五行八字起名
100天的春季 100分的美丽 | 贵州春日漫游“指南”
用“锴”字起名字有什么需要注意的吗?
科举制创立的原因是什么?历史意义是?
征收“超级富豪税”有无可能?
告别完美主义,拥抱真实的你!