您好,登錄后才能下訂單哦!
本篇內容介紹了“Android中TextView自動適配文本大小的解決方案有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
官方推出的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);
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>
效果如下:
“Android中TextView自動適配文本大小的解決方案有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。