網(wǎng)站首頁 編程語言 正文
TextView文本大小自動(dòng)適配與TextView邊距的去除
標(biāo)題太難取了,其實(shí)本文主要就是講如何控制文本大小,讓其自動(dòng)適配寬度,其次我們還需要精準(zhǔn)控制Text的高度和寬度間距等屬性。
一般我們的布局都是分 match parent 和 wrap content 而他們的自動(dòng)方式又有所不同。下面看看都有哪些方式來實(shí)現(xiàn)!
一、Autosizing的方式(固定寬度)
官方推出的TextView的Autosizing方式,在寬度固定的情況下,可以設(shè)置最大文本Size和最小文本Size和每次縮放粒度,非常方便的就能實(shí)現(xiàn)該功能。
<TextView android:layout_width="340dp" android:layout_height="50dp" android:background="@drawable/shape_bg_008577" android:gravity="center_vertical" android:maxLines="1" android:text="這是標(biāo)題,該標(biāo)題的名字比較長,產(chǎn)品要求不換行全部顯示出來" android:textSize="18sp" android:autoSizeTextType="uniform" android:autoSizeMaxTextSize="18sp" android:autoSizeMinTextSize="10sp" android:autoSizeStepGranularity="1sp"/>
- autoSizeTextType:設(shè)置 TextView 是否支持自動(dòng)改變文本大小,none 表示不支持,uniform 表示支持。
- autoSizeMinTextSize:最小文字大小,例如設(shè)置為10sp,表示文字最多只能縮小到10sp。
- autoSizeMaxTextSize:最大文字大小,例如設(shè)置為18sp,表示文字最多只能放大到18sp。
- autoSizeStepGranularity:縮放粒度,即每次文字大小變化的數(shù)值,例如設(shè)置為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 的方式類似,一般是測(cè)量 TextView 字體所占的寬度與 TextView 控件的寬度對(duì)比,動(dòng)態(tài)改變 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" />
效果和方案一類似
三、使用工具類自行計(jì)算(非控件固定寬度)
把第二步中自定義View計(jì)算寬度的方法抽取出來,我們可以可以得到一個(gè)工具類如下:
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如下:
右側(cè)的LinearLayout中需要包含2個(gè)文本 一個(gè)14sp 一個(gè)是30sp,同時(shí)居中但是要金額的文本自動(dòng)適配大小。
<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個(gè)都是wrap content,那么如何實(shí)現(xiàn)這種適應(yīng)寬度+多布局的變長寬度效果呢。其實(shí)就是需要我們調(diào)用方法手動(dòng)的計(jì)算金額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)
效果如下:(該效果是去除邊距之后的對(duì)齊效果)
四、去除TextView的邊距
我們都知道TextView繪制的時(shí)候并非是我們平常自定義View那種drawText,而是分為幾塊區(qū)域,基于基線繪制文本,并加入了上下左右的間距。
而不同的TestSize 它的間距還不同,比如上文中我們一個(gè)很小的 TextView 和一個(gè)很大的 TextView 在一起排列的時(shí)候,特別是大的 TextView 還是 AutoSize 的情況下,實(shí)現(xiàn)一些對(duì)齊效果就很難實(shí)現(xiàn),我們就需要考慮到去除間距,只保留上圖灰色的矩形框來繪制文本。
代碼如下:
public class NoPaddingTextView extends AppCompatTextView {
private Paint mPaint = getPaint();
private Rect mBounds = new Rect();
private Boolean mRemoveFontPadding = false;//是否去除字體內(nèi)邊距,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();
}
/**
* 計(jì)算文本參數(shù)
*/
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 的大小和間距,想讓文本多大就多大,想在哪展示就在哪展示,很方便的實(shí)現(xiàn)對(duì)齊和絕大部分文本的展示效果了。
總結(jié)
原文鏈接:https://juejin.cn/post/7106714269730914312
相關(guān)推薦
- 2022-02-24 TypeError: ‘Serializer‘ object is not callable
- 2022-09-26 Transformer模型Encoder和Decoder的Pytorch逐行實(shí)現(xiàn)
- 2023-01-17 Android?Service開發(fā)應(yīng)用實(shí)例_Android
- 2022-12-09 Python命名空間與作用域深入全面詳解_python
- 2022-09-05 Spring 解決循環(huán)依賴
- 2021-12-31 使用go實(shí)現(xiàn)一個(gè)超級(jí)mini的消息隊(duì)列的示例代碼_Golang
- 2023-04-19 清楚詳解Android?進(jìn)程間圖傳遞圖形buffer原理_Android
- 2022-03-19 C#?壓榨cpu的辦法(推薦)_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支