自定义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方式简单易用,适合大多数情况
- 工具类方式则提供了更大的灵活性,特别是在宽度不固定的情况下
开发者可以根据具体需求选择最适合的方案,确保应用在各种设备上都能保持良好的显示效果。
热门推荐
AAFCO 認證是什麼?毛孩食安的守門員,寵物飼料挑選指南
分子间氢键与物质性质的调控:溶剂效应和药物设计
什么会影响金价?影响金价的因素如何进行分析和了解?
从落后到先进:上海羽毛球运动百年发展史
《永远是我的女孩》:家庭、爱情与社区的情感纽带
小折叠椅材料分类,教你如何进行选购
国内股票怎样进行理性的投资选择?这些选择怎样符合市场趋势?
脑机接口概念股再起飞!机构研判:大规模应用的质变前夜
【健康科普】转移性肝癌再认识!
什么是机器人流程自动化
如何进行吞咽障碍康复训练?
邯郸市第二医院:医疗服务“微创新” 患者体验“大提升”
了解Go interface以及其所带来的开销
纯碱为何跌跌不休
清朝的改土归流政策及其原因
因停车费纠纷堵塞小区停车场10小时,3人被榆林清涧警方行拘
认知、大脑与智能,2024年度书单推荐
产后心理护理:全面关爱新手妈妈
产后心理康复,重拾自我快乐
全球顶尖的四大设计学院分别是哪所
欧洲车市 | 2024年法国汽车市场的特点
征西将军:古代官职在现代的对应解析
Cureus:髋部骨折患者术后增加肌肉量的康复方案研究
踝部骨折治疗
深海鱼油的功效与使用指南
UN38.3认证完全指南:测试要求、包装规范及申请流程
关羽:一个忠义勇猛的败军之将,为什么会成为华夏的武圣?
关羽姓氏之谜:他真的不姓关吗?
流程图拓扑图能将复杂问题简单化,放在可视化大屏中间再合适不过
洛杉矶快艇队如何运用运动科学优化球员表现