溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android中TextView自動適配文本大小的解決方案有哪些

發(fā)布時間:2022-06-09 14:59:49 來源:億速云 閱讀:158 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Android中TextView自動適配文本大小的解決方案有哪些”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

    一、Autosizing的方式(固定寬度)

    官方推出的TextView的Autosizing方式,在寬度固定的情況下,可以設(shè)置最大文本Size和最小文本Size和每次縮放粒度,非常方便的就能實現(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="這是標題,該標題的名字比較長,產(chǎn)品要求不換行全部顯示出來"
            android:textSize="18sp"
            android:autoSizeTextType="uniform"
            android:autoSizeMaxTextSize="18sp"
            android:autoSizeMinTextSize="10sp"
            android:autoSizeStepGranularity="1sp"/>
    • autoSizeTextType:設(shè)置 TextView 是否支持自動改變文本大小,none 表示不支持,uniform 表示支持。

    • autoSizeMinTextSize:最小文字大小,例如設(shè)置為10sp,表示文字最多只能縮小到10sp。

    • autoSizeMaxTextSize:最大文字大小,例如設(shè)置為18sp,表示文字最多只能放大到18sp。

    • autoSizeStepGranularity:縮放粒度,即每次文字大小變化的數(shù)值,例如設(shè)置為1sp,表示每次縮小或放大的值為1sp。

    效果:

    Android中TextView自動適配文本大小的解決方案有哪些

    如果在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 控件的寬度對比,動態(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"
            />

    效果和方案一類似

    三、使用工具類自行計算(非控件固定寬度)

    把第二步中自定義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如下:

    Android中TextView自動適配文本大小的解決方案有哪些

    右側(cè)的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,那么如何實現(xiàn)這種適應(yīng)寬度+多布局的變長寬度效果呢。其實就是需要我們調(diào)用方法手動的計算金額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)

    效果如下:(該效果是去除邊距之后的對齊效果)

    Android中TextView自動適配文本大小的解決方案有哪些

    Android中TextView自動適配文本大小的解決方案有哪些

    四、去除TextView的邊距

    我們都知道TextView繪制的時候并非是我們平常自定義View那種drawText,而是分為幾塊區(qū)域,基于基線繪制文本,并加入了上下左右的間距。

    Android中TextView自動適配文本大小的解決方案有哪些

    而不同的TestSize 它的間距還不同,比如上文中我們一個很小的 TextView 和一個很大的 TextView 在一起排列的時候,特別是大的 TextView 還是 AutoSize 的情況下,實現(xiàn)一些對齊效果就很難實現(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();
        }
    
        /**
         * 計算文本參數(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>

    效果如下:

    Android中TextView自動適配文本大小的解決方案有哪些

    “Android中TextView自動適配文本大小的解決方案有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI