当前位置:网站首页>TextView文本大小自动适配与TextView边距的去除
TextView文本大小自动适配与TextView边距的去除
2022-06-11 08:42:00 【码中之牛】
标题太难取了,其实本文主要就是讲如何控制文本大小,让其自动适配宽度,其次我们还需要精准控制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 的大小和间距,想让文本多大就多大,想在哪展示就在哪展示,很方便的实现对齐和绝大部分文本的展示效果了。
边栏推荐
- 马志强:语音识别技术研究进展和应用落地分享丨RTC Dev Meetup
- (一)aac开篇-核心组件原理之Lifecycle、LiveData、ViewModel与源码分析技巧(转载)
- Wood board ISO 5660-1 heat release rate mapping test
- PVC 塑料片BS 476-6 火焰传播性能测定
- 剑指 Offer 51. 数组中的逆序对
- Redis6 entry-level tutorial. There are integration cases. You can directly see the integration cases. It is easy to get started
- Polymorphic interview questions
- Not eligible for getting processed by all beanpostprocessors
- [software tool] installation ffmpeg
- leetcode - 518. 零钱兑换 II
猜你喜欢

Web design and website planning assignment 13 making video playlists

盘它!用「飞项」轻松管理各类型项目

处理RAW格式的图像,需要什么软件?

剑指 Offer 40. 最小的k个数

Sword finger offer 62 The last remaining number in the circle

Web design and website planning assignment 12 online registration form

Implementation of CRF for named entity recognition

补2:圆环回原点问题

CodeTop - 排序奇升偶降链表

leetcode - 460. LFU 缓存
随机推荐
Standardized compilation knowledge
Qiao NPMS: get the download volume of NPM packages
[programming development] markdown notes tutorial
Mazhiqiang: research progress and application of speech recognition technology -- RTC dev Meetup
光伏板怎么申请ASTM E108阻燃测试?
九九乘法表
领导让我重写测试代码,我也要照办嘛?
leetcode - 518. 零钱兑换 II
Type of SQL command (incomplete)
go for it Easily manage all types of items with "flying items"
win10家庭版如何连接远程桌面
木板ISO 5660-1 热量释放速率摸底测试
Web design and website planning assignment 12 online registration form
Getting started with Zipkin
【clickhouse专栏】新建库角色用户初始化
Sword finger offer 62 The last remaining number in the circle
硅树脂油漆申请美国标准UL 790 Class A 合适吗?
In place reversal of a LinkedList
一些学习记录i=
ActiveMQ简单教程,适合初学者,学习笔记yyds