Android中TextView自动适配文本大小的几种解决方案
作者:newki 发布时间:2022-05-28 09:08:01
TextView文本大小自动适配与TextView边距的去除
标题太难取了,其实本文主要就是讲如何控制文本大小,让其自动适配宽度,其次我们还需要精准控制Text的高度和宽度间距等属性。
一般我们的布局都是分 match parent 和 wrap content 而他们的自动方式又有所不同。下面看看都有哪些方式来实现!
一、Autosizing的方式(固定宽度)
官方推出的TextView的Autosizing方式,在宽度固定的情况下,可以设置最大文本Size和最小文本Size和每次缩放粒度,非常方便的就能实现该功能。
<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"/>
autoSizeTextType:设置 TextView 是否支持自动改变文本大小,none 表示不支持,uniform 表示支持。
autoSizeMinTextSize:最小文字大小,例如设置为10sp,表示文字最多只能缩小到10sp。
autoSizeMaxTextSize:最大文字大小,例如设置为18sp,表示文字最多只能放大到18sp。
autoSizeStepGranularity:缩放粒度,即每次文字大小变化的数值,例如设置为1sp,表示每次缩小或放大的值为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);
二、自定义View的方式(固定宽度)
github上有很多这种的TextView自定义,类似这样的。
其核心思想和上面的 Autosizing 的方式类似,一般是测量 TextView 字体所占的宽度与 TextView 控件的宽度对比,动态改变 TextView 的字体大小。
它们的类似用法如下:
<ru.igla.widget.AutoSizeTextView
android:id="@+id/tvFullscreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Long ancestry"
android:textColor="@android:color/black"
android:background="@android:color/white"
android:textSize="500sp"
android:maxLines="500"
android:gravity="center"
android:ellipsize="@null"
android:autoText="false"
android:autoLink="none"
android:linksClickable="false"
android:singleLine="false"
android:padding="0px"
android:includeFontPadding="false"
android:textAlignment="center"
android:typeface="normal"
android:layout_gravity="center"
android:textStyle="normal"
app:minTxtSize="8sp"
/>
效果和方案一类似
三、使用工具类自行计算(非控件固定宽度)
把第二步中自定义View计算宽度的方法抽取出来,我们可以可以得到一个工具类如下:
private 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--;
textPaintClone.setTextSize(trySize);
}
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
Demo如下:
右侧的LinearLayout中需要包含2个文本 一个14sp 一个是30sp,同时居中但是要金额的文本自动适配大小。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_15dp"
android:layout_marginRight="@dimen/d_15dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_job_detail_dollar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$"
android:textColor="@color/black"
android:textSize="@dimen/job_detail_message_size"/>
<TextView
android:id="@+id/text_view_hourly_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_2dp"
android:singleLine="true"
android:text="-"
android:textColor="@color/job_detail_black"
android:textSize="30sp" />
</LinearLayout>
可以看到2个都是wrap content,那么如何实现这种适应宽度+多布局的变长宽度效果呢。其实就是需要我们调用方法手动的计算金额TextView的宽度
int mFullNameTVMaxWidth = CommUtils.dip2px(60);
// mTextViewHourlyRate.setText(totalMoney);
// while (true) {
// float measureTextWidth = mTextViewHourlyRate.getPaint().measureText(totalMoney);
// if (measureTextWidth > mFullNameTVMaxWidth) {
// int textSize = (int) mTextViewHourlyRate.getTextSize();
// textSize = textSize - 2;
// mTextViewHourlyRate.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
// } else {
// break;
// }
// }
adjustTvTextSize(mTextViewHourlyRate,mFullNameTVMaxWidth,totalMoney)
效果如下:(该效果是去除边距之后的对齐效果)
四、去除TextView的边距
我们都知道TextView绘制的时候并非是我们平常自定义View那种drawText,而是分为几块区域,基于基线绘制文本,并加入了上下左右的间距。
而不同的TestSize 它的间距还不同,比如上文中我们一个很小的 TextView 和一个很大的 TextView 在一起排列的时候,特别是大的 TextView 还是 AutoSize 的情况下,实现一些对齐效果就很难实现,我们就需要考虑到去除间距,只保留上图灰色的矩形框来绘制文本。
代码如下:
public class NoPaddingTextView extends AppCompatTextView {
private Paint mPaint = getPaint();
private Rect mBounds = new Rect();
private Boolean mRemoveFontPadding = false;//是否去除字体内边距,true:去除 false:不去除
public NoPaddingTextView(Context context) {
super(context);
}
public NoPaddingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttributes(context, attrs);
}
public NoPaddingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttributes(context, attrs);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mRemoveFontPadding) {
calculateTextParams();
setMeasuredDimension(mBounds.right - mBounds.left, -mBounds.top + mBounds.bottom);
}
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
protected void onDraw(Canvas canvas) {
drawText(canvas);
}
/**
* 初始化属性
*/
private void initAttributes(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NoPaddingTextView);
mRemoveFontPadding = typedArray.getBoolean(R.styleable.NoPaddingTextView_removeDefaultPadding, false);
typedArray.recycle();
}
/**
* 计算文本参数
*/
private String calculateTextParams() {
String text = getText().toString();
int textLength = text.length();
mPaint.getTextBounds(text, 0, textLength, mBounds);
if (textLength == 0) {
mBounds.right = mBounds.left;
}
return text;
}
/**
* 绘制文本
*/
private void drawText(Canvas canvas) {
String text = calculateTextParams();
int left = mBounds.left;
int bottom = mBounds.bottom;
mBounds.offset(-mBounds.left, -mBounds.top);
mPaint.setAntiAlias(true);
mPaint.setColor(getCurrentTextColor());
canvas.drawText(text, (float) (-left), (float) (mBounds.bottom - bottom), mPaint);
}
}
使用:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_15dp"
android:layout_marginRight="@dimen/d_15dp"
android:gravity="center"
android:orientation="horizontal">
<com.guadou.componentservice.widget.view.NoPaddingTextView
android:id="@+id/tv_job_detail_dollar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$"
android:textColor="@color/black"
android:background="@color/yellow"
android:textSize="@dimen/job_detail_message_size"
app:removeDefaultPadding="true" />
<com.guadou.componentservice.widget.view.NoPaddingTextView
android:id="@+id/text_view_hourly_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_2dp"
android:singleLine="true"
android:text="-"
android:background="@color/red"
android:textColor="@color/job_detail_black"
android:textSize="30sp"
app:removeDefaultPadding="true" />
</LinearLayout>
效果如下:
到此我们就能随心的控制 TextView 的大小和间距,想让文本多大就多大,想在哪展示就在哪展示,很方便的实现对齐和绝大部分文本的展示效果了。
来源:https://juejin.cn/post/7106714269730914312
猜你喜欢
- 前言:如果让大家说出一款国内比较热门的社交软件,那无疑就是QQ和微信了,说到微信,无不例外的会想到微信公众号和小程序,所以现在它们已经是很多
- 本文为大家分享了maven环境变量配置的具体方法,供大家参考,具体内容如下一、maven环境配置1.解压apache-maven
- Java语言是SUN(Stanford University Network,斯坦福大学网络公司)公司1995年推出的一门高级编程语言,起初
- 本文实例讲述了Android编程实现webview将网页打包成apk的方法。分享给大家供大家参考,具体如下:功能非常简单,而且乍一看没什么特
- 你以前听到的谈论关于Java8的所有都是围绕lambda表达式. 但它仅仅是Java8的一部分. Java 8 有许多新特性—一些强大的新类
- 本文实例为大家分享了Android自定义双向滑动控件的具体代码,供大家参考,具体内容如下先看一下效果图1.SeekBarPressure工具
- 序言for循环语句是java循环语句中最常用的循环语句,一般用在循环次数已知的情况下使用。for循环语句的语法格式如下:java语言 for
- 本文实例讲述了Java Swing组件文件选择器JFileChooser简单用法。分享给大家供大家参考,具体如下:先来看效果:说明:选择文件
- 需求: 给定一个URL地址, 例如: http://www.cncounter.com/tools/shorturl.php, 解析对应的I
- javascript checkbox全选和反选的简单实现 发现这样写checkbox全选和反选最简洁明了。function te
- 多对一(Many-to-One)映射多对一(many-to-one)关联是最常见的关联关系,其中一个对象可以与多个对象相关联。例如,一个相同
- MyBatis注解实现动态SQL在 Mybatis 中,使用注解可以很方便的进行sql操作,但很多动态 SQL 都是由 xml 配置实现的。
- 概述Spring Boot 监控核心是 spring-boot-starter-actuator 依赖,增加依赖后, Spring Boot
- private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAd
- 概述ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码。目标是能够对QR编码、Data Matrix、UPC的1D
- Struct的理论看过好一些,可是工作上基本没有应用过,Class倒处处都有。难道Struct就没有什么使用价值吗?搜了一下如何在类和结构中
- 1.定义字符串字符串常见的构造方式如下:String s1 = "with";String s2 = new Strin
- C#查看堆栈通常是在异常处理中,出现异常之后通过异常的堆栈可以很方便的得到出现这个错误的代码调用路径。这个很有用,是否可以在没有异常出现时使
- 一、封装一个工具类1、简易版package net.aexit.construct.acceptance.websky.utils;impo
- 引言前文中了解到AQS借助LockSupport.park和LockSupport.unpark完成线程的阻塞和唤醒,那么LockSuppo