<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
標題太難取了,其實本文主要就是講如何控制文字大小,讓其自動適配寬度,其次我們還需要精準控制Text的高度和寬度間距等屬性。
一般我們的佈局都是分 match parent 和 wrap content 而他們的自動方式又有所不同。下面看看都有哪些方式來實現!
官方推出的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"/>
效果:
如果在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);
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繪製的時候並非是我們平常自定義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 的大小和間距,想讓文字多大就多大,想在哪展示就在哪展示,很方便的實現對齊和絕大部分文字的展示效果了。
到此這篇關於Android中TextView自動適配文字大小的幾種解決方案的文章就介紹到這了,更多相關Android TextView自動適配文字大小內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45