自定义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方式简单易用,适合大多数情况
- 工具类方式则提供了更大的灵活性,特别是在宽度不固定的情况下
开发者可以根据具体需求选择最适合的方案,确保应用在各种设备上都能保持良好的显示效果。
热门推荐
涤纶纤维(聚酯纤维)优缺点列举
新生儿鼻子堵了怎么弄
深入解析USDT:全球加密货币市场中不可或缺的稳定币巨头
跨国婚姻如何避免配偶签证被拒
刘邦为何不考虑戚姬刘如意母子的安全,在临死前处死皇后吕雉?
让“文博热”更持久:代表委员为博物馆发展建言献策
如何评估研发团队的技术投资回报率
二氧化硅:从结构到应用的全面解析
电脑数据迁移到另一台电脑?新旧电脑数据转移最快的方法
表白被拒后,如何优雅地处理这段感情?
金豆扦插繁殖完全指南:从选材到养护的详细步骤
中国人起名字讲究字辈排行,你的家族辈分谱是什么?
以科技创新促进产业体系的完整性先进性安全性
@所有师生、家长 请做好春季传染病防控
如何保证睡觉不打呼噜小妙招
华为IPD流程如何确保产品质量
新能源汽车到底值不值得购买,混动和纯电该怎么选?
债务违约金怎么计算公式
《沁园春·雪》的艺术特色和思想内涵
白加黑与头孢能否同服?用药安全与辅助治疗详解
API如何设置跨域
张文裕王承书院士伉俪:矢志不渝报国心 留得正气在人间
VMware Workstation性能优化指南
如何提高软件团队竞争力
互动投票:提升活动参与感与互动性的重要工具
解放战争时期,五大野战军有53个纵队,其中这8个纵队的实力最强
贫血逆袭记:用“药”有方更从容
平板与笔记本电脑:性能、使用频次与场景的深度解析
二审上诉流程是什么?
无线漫游详解:概念、分类及原理