วิธีปรับขนาดแบบอักษรให้พอดีกับมุมมองข้อความ


178

มีวิธีใดบ้างใน Android ที่จะปรับ textize ใน textview ให้พอดีกับพื้นที่ที่มันครอบครอง?

เช่นฉันกำลังใช้TableLayoutและเพิ่มหลาย ๆTextViewแถวในแต่ละแถว เนื่องจากฉันไม่ต้องการให้TextViews ห่อข้อความฉันจึงเห็นว่ามันลดขนาดตัวอักษรของเนื้อหา

ความคิดใด ๆ

ฉันลองmeasureTextแล้ว แต่เนื่องจากฉันไม่ทราบขนาดของคอลัมน์มันจึงลำบากที่จะใช้ นี่คือรหัสที่ฉันต้องการเปลี่ยนขนาดตัวอักษรเป็นสิ่งที่เหมาะกับ

TableRow row = new TableRow(this);   
for (int i=0; i < ColumnNames.length; i++) {    
    TextView textColumn = new TextView(this);      
    textColumn.setText(ColumnNames[i]);
    textColumn.setPadding(0, 0, 1, 0);
    textColumn.setTextColor(getResources().getColor(R.drawable.text_default));          
    row.addView(textColumn, new TableRow.LayoutParams()); 
} 
table.addView(row, new TableLayout.LayoutParams());  

ตรวจสอบโซลูชันของฉันตามรหัสของ dunni ที่นี่stackoverflow.com/questions/5033012/…หมายเหตุ: ฉันไม่ได้ติดตั้งด้วยลูป PS: ขอบคุณ dunni
vsm

คำตอบ:


129

วิธีแก้ปัญหาด้านล่างรวมคำแนะนำทั้งหมดไว้ที่นี่ มันเริ่มต้นด้วยสิ่งที่โพสต์สร้างสรรค์โดย Dunni มันใช้การค้นหาแบบไบนารี่เช่น gjpc แต่มันสามารถอ่านได้มากกว่า นอกจากนี้ยังรวมถึงการแก้ไขข้อบกพร่องของ gregm และการแก้ไขข้อผิดพลาดของฉันเอง

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialise();
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialise();
    }

    private void initialise() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        //max size defaults to the initially specified text size unless it is too small
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth) 
    { 
        if (textWidth <= 0)
            return;
        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
        float hi = 100;
        float lo = 2;
        final float threshold = 0.5f; // How close we have to be

        mTestPaint.set(this.getPaint());

        while((hi - lo) > threshold) {
            float size = (hi+lo)/2;
            mTestPaint.setTextSize(size);
            if(mTestPaint.measureText(text) >= targetWidth) 
                hi = size; // too big
            else
                lo = size; // too small
        }
        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int height = getMeasuredHeight();
        refitText(this.getText().toString(), parentWidth);
        this.setMeasuredDimension(parentWidth, height);
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
        refitText(text.toString(), this.getWidth());
    }

    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        if (w != oldw) {
            refitText(this.getText().toString(), w);
        }
    }

    //Attributes
    private Paint mTestPaint;
}

9
ขอบคุณสำหรับการรวมข้อเสนอแนะทั้งหมด ฉันเห็นว่าการแก้ปัญหานั้นคำนึงถึงความกว้างเท่านั้น ปัญหาของฉันคือความรักเกินความสูง
AlikElzin-kilaka

3
โอ้ดูเหมือนว่าจะทำงานบางส่วนในขณะทำงาน บนอุปกรณ์เลียนแบบข้อความจะถูกตัดครึ่งทาง ในตัวแก้ไขโครงร่าง Eclipse มันดูดี ความคิดใด ๆ
AlikElzin-kilaka

1
โพสต์นี้ดูเหมือนว่ามันจะทำเคล็ดลับ (การเพิ่มแอตทริบิวต์ xml ที่กำหนดเองสำหรับ hi / lo): stackoverflow.com/a/8090772/156611
Ed Sinek

7
นี่เป็นทางออกที่ยอดเยี่ยม! ในกรณีที่คนอื่นไม่คุ้นเคยกับการพัฒนา Android และไม่รู้วิธีใช้มุมมองแบบขยายใน XML ดูเหมือนว่า: <com.example.zengame1.FontFitTextView android:paddingTop="5dip" android:id="@+id/childs_name" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:layout_gravity="center" android:textSize="@dimen/text_size"/>
Casey Murray

2
การทำงานที่ดี! ใช้งานได้กับปุ่มต่างๆ เพื่อดูแลความสูงของ textview ที่ตั้งไว้float hi = this.getHeight() - this.getPaddingBottom() - this.getPaddingTop();
AlexGuti

28

ฉันได้เขียนคลาสที่ขยาย TextView และทำสิ่งนี้ เพียงแค่ใช้ measureText ตามที่คุณแนะนำ โดยทั่วไปจะมีขนาดตัวอักษรสูงสุดและขนาดตัวอักษรขั้นต่ำ (ซึ่งสามารถเปลี่ยนแปลงได้) และมันจะทำงานผ่านขนาดระหว่างพวกเขาในการลดลงของ 1 จนกว่าจะพบขนาดที่ใหญ่ที่สุดที่จะพอดี ไม่หรูหราโดยเฉพาะอย่างยิ่ง แต่ฉันไม่รู้วิธีอื่นใด

นี่คือรหัส:

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialise();
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialise();
    }

    private void initialise() {
        testPaint = new Paint();
        testPaint.set(this.getPaint());
        //max size defaults to the intially specified text size unless it is too small
        maxTextSize = this.getTextSize();
        if (maxTextSize < 11) {
            maxTextSize = 20;
        }
        minTextSize = 10;
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth) { 
        if (textWidth > 0) {
            int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
            float trySize = maxTextSize;

            testPaint.setTextSize(trySize);
            while ((trySize > minTextSize) && (testPaint.measureText(text) > availableWidth)) {
                trySize -= 1;
                if (trySize <= minTextSize) {
                    trySize = minTextSize;
                    break;
                }
                testPaint.setTextSize(trySize);
            }

            this.setTextSize(trySize);
        }
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
        refitText(text.toString(), this.getWidth());
    }

    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        if (w != oldw) {
            refitText(this.getText().toString(), w);
        }
    }

    //Getters and Setters
    public float getMinTextSize() {
        return minTextSize;
    }

    public void setMinTextSize(int minTextSize) {
        this.minTextSize = minTextSize;
    }

    public float getMaxTextSize() {
        return maxTextSize;
    }

    public void setMaxTextSize(int minTextSize) {
        this.maxTextSize = minTextSize;
    }

    //Attributes
    private Paint testPaint;
    private float minTextSize;
    private float maxTextSize;

}

11
โดยทั่วไปแล้วการค้นหาแบบไบนารีจะเร็วกว่าการค้นหาแบบเชิงเส้น
Ted Hopp

ฉันคิดว่ามันจะสมเหตุสมผลมากกว่าที่จะทำ refitText ที่ "onLayout" มากกว่า "onSizeChanged"
Jacky

คุณช่วยดูปัญหาของฉันได้ที่stackoverflow.com/questions/36265448/…
Muhammad

17

นี่คือSpeedplaneFontFitTextViewแต่จะลดขนาดตัวอักษรเฉพาะเมื่อจำเป็นเพื่อให้พอดีกับข้อความและคงขนาดตัวอักษรไว้เป็นอย่างอื่น ไม่เพิ่มขนาดตัวอักษรให้พอดีกับความสูง

public class FontFitTextView extends TextView {

    // Attributes
    private Paint mTestPaint;
    private float defaultTextSize;

    public FontFitTextView(Context context) {
        super(context);
        initialize();
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    private void initialize() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        defaultTextSize = getTextSize();
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth) {

        if (textWidth <= 0 || text.isEmpty())
            return;

        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();

        // this is most likely a non-relevant call
        if( targetWidth<=2 )
            return;

        // text already fits with the xml-defined font size?
        mTestPaint.set(this.getPaint());
        mTestPaint.setTextSize(defaultTextSize);
        if(mTestPaint.measureText(text) <= targetWidth) {
            this.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize);
            return;
        }

        // adjust text size using binary search for efficiency
        float hi = defaultTextSize;
        float lo = 2;
        final float threshold = 0.5f; // How close we have to be
        while (hi - lo > threshold) {
            float size = (hi + lo) / 2;
            mTestPaint.setTextSize(size);
            if(mTestPaint.measureText(text) >= targetWidth ) 
                hi = size; // too big
            else 
                lo = size; // too small

        }

        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int height = getMeasuredHeight();
        refitText(this.getText().toString(), parentWidth);
        this.setMeasuredDimension(parentWidth, height);
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start,
            final int before, final int after) {
        refitText(text.toString(), this.getWidth());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (w != oldw || h != oldh) {
            refitText(this.getText().toString(), w);
        }
    }

}

นี่คือตัวอย่างวิธีการใช้ใน xml:

<com.your.package.activity.widget.FontFitTextView
    android:id="@+id/my_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="My Text"
    android:textSize="60sp" />

นี่จะทำให้ขนาดตัวอักษรอยู่ที่ 60sp ตราบใดที่ตัวอักษรพอดีกับความกว้าง หากข้อความยาวขึ้นก็จะลดขนาดตัวอักษร ในกรณีนี้ความสูงนอกจากนี้ยังจะมีการเปลี่ยนแปลงเพราะTextViewheight=wrap_content

หากคุณพบข้อบกพร่องใด ๆ อย่าลังเลที่จะแก้ไข


คุณใช้มันอย่างไร ฉันได้เพิ่มตัวอย่างของวิธีการใช้คำตอบของฉัน ฉันได้ทดสอบมันกับ Android, emulators และ ADT Graphical Layout Editor
sulai

โดยพื้นฐานแล้วฉันไม่ได้ระบุความสูงที่เฉพาะเจาะจง onMeasure ของคุณอนุญาตให้มุมมองเข้าครอบครองได้ถ้าต้องการ ฉันจัดการหาวิธีแก้ปัญหาโดยเปลี่ยนบรรทัดสุดท้ายในรูทีนเป็นthis.setMeasuredDimension(parentWidth, height);
PearsonArtPhoto

1
การป้อนข้อมูลที่ดีผมแก้ไขรหัส :) ตอนนี้ก็ทำงานร่วมกับและmatch_parent wrap_content
sulai

ทำไมคุณถึงทดสอบการเขียนสตริงว่าง "" .equals (s) แทนที่จะเป็นเพียงแค่ s.isEmpty ()? หรือ s.length () == 0 ไม่เข้าใจว่าทำไมฉันสามารถเห็นการทดสอบความเท่าเทียมกันเหล่านี้บางครั้ง
Zordid

1
@PratikButani ขอบคุณที่ชี้นำสิ่งนี้ เพื่อเทียบเท่าจะเป็นtext.isEmpty() "".equals(text)
sulai

14

นี่คือโซลูชันของฉันที่ทำงานกับอีมูเลเตอร์และโทรศัพท์ แต่ไม่ค่อยดีสำหรับตัวแก้ไขเลย์เอาต์ Eclipse มันเป็นแรงบันดาลใจจากรหัส kilaka แต่ขนาดของข้อความที่ไม่ได้มาจากสี แต่จากการวัด TextView measure(0, 0)ที่ตัวเองเรียกร้อง

คลาส Java:

public class FontFitTextView extends TextView
{
    private static final float THRESHOLD = 0.5f;

    private enum Mode { Width, Height, Both, None }

    private int minTextSize = 1;
    private int maxTextSize = 1000;

    private Mode mode = Mode.None;
    private boolean inComputation;
    private int widthMeasureSpec;
    private int heightMeasureSpec;

    public FontFitTextView(Context context) {
            super(context);
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
    }

    public FontFitTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);

            TypedArray tAttrs = context.obtainStyledAttributes(attrs, R.styleable.FontFitTextView, defStyle, 0);
            maxTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_maxTextSize, maxTextSize);
            minTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_minTextSize, minTextSize);
            tAttrs.recycle();
    }

    private void resizeText() {
            if (getWidth() <= 0 || getHeight() <= 0)
                    return;
            if(mode == Mode.None)
                    return;

            final int targetWidth = getWidth();
            final int targetHeight = getHeight();

            inComputation = true;
            float higherSize = maxTextSize;
            float lowerSize = minTextSize;
            float textSize = getTextSize();
            while(higherSize - lowerSize > THRESHOLD) {
                    textSize = (higherSize + lowerSize) / 2;
                    if (isTooBig(textSize, targetWidth, targetHeight)) {
                            higherSize = textSize; 
                    } else {
                            lowerSize = textSize;
                    }
            }
            setTextSize(TypedValue.COMPLEX_UNIT_PX, lowerSize);
            measure(widthMeasureSpec, heightMeasureSpec);
            inComputation = false;
    }

    private boolean isTooBig(float textSize, int targetWidth, int targetHeight) {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
            measure(0, 0);
            if(mode == Mode.Both)
                    return getMeasuredWidth() >= targetWidth || getMeasuredHeight() >= targetHeight;
            if(mode == Mode.Width)
                    return getMeasuredWidth() >= targetWidth;
            else
                    return getMeasuredHeight() >= targetHeight;
    }

    private Mode getMode(int widthMeasureSpec, int heightMeasureSpec) {
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY)
                    return Mode.Both;
            if(widthMode == MeasureSpec.EXACTLY)
                    return Mode.Width;
            if(heightMode == MeasureSpec.EXACTLY)
                    return Mode.Height;
            return Mode.None;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if(!inComputation) {
                    this.widthMeasureSpec = widthMeasureSpec;
                    this.heightMeasureSpec = heightMeasureSpec;
                    mode = getMode(widthMeasureSpec, heightMeasureSpec);
                    resizeText();
            }
    }

    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
            resizeText();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            if (w != oldw || h != oldh)
                    resizeText();
    }

    public int getMinTextSize() {
            return minTextSize;
    }

    public void setMinTextSize(int minTextSize) {
            this.minTextSize = minTextSize;
            resizeText();
    }

    public int getMaxTextSize() {
            return maxTextSize;
    }

    public void setMaxTextSize(int maxTextSize) {
            this.maxTextSize = maxTextSize;
            resizeText();
    }
}

ไฟล์แอตทริบิวต์ XML:

<resources>
    <declare-styleable name="FontFitTextView">
        <attr name="minTextSize" format="dimension" />
        <attr name="maxTextSize" format="dimension" />
    </declare-styleable>
</resources>

ตรวจสอบGitHub ของฉันสำหรับรุ่นล่าสุดของชั้นนี้ ฉันหวังว่ามันจะมีประโยชน์สำหรับใครบางคน หากพบข้อบกพร่องหรือหากรหัสต้องการคำอธิบายอย่าลังเลที่จะเปิดปัญหาใน Github


มันใช้งานได้ดีกับ Galaxy Nexus ของฉัน แต่ฉันมีปัญหากับอุปกรณ์ที่มีหน้าจอขนาดเล็ก
Tony Ceralva

คุณมีปัญหาอะไรกับอุปกรณ์ที่มีหน้าจอขนาดเล็ก
yDelouis

ขออภัยปัญหาไม่ได้อยู่กับหน้าจอขนาดเล็กมุมมองของคุณไม่ทำงานในอุปกรณ์ทั้งหมดที่ใช้ Android 4.0 รวมตัวจำลอง ฉันเปิดปัญหาใหม่ใน GitHub ของคุณ
Tony Ceralva

12

ขอบคุณมากที่จะhttps://stackoverflow.com/users/234270/speedplane คำตอบที่ดี!

นี่คือรุ่นที่ปรับปรุงของการตอบสนองของเขาที่ยังดูแลส่วนสูงและมาพร้อมกับแอตทริบิวต์ maxFontSize เพื่อ จำกัด ขนาดตัวอักษร (มีประโยชน์ในกรณีของฉันดังนั้นฉันจึงต้องการแบ่งปัน):

package com.<your_package>;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;


public class FontFitTextView extends TextView
{

    private Paint mTestPaint;
    private float maxFontSize;
    private static final float MAX_FONT_SIZE_DEFAULT_VALUE = 20f;

    public FontFitTextView(Context context)
    {
        super(context);
        initialise(context, null);
    }

    public FontFitTextView(Context context, AttributeSet attributeSet)
    {
        super(context, attributeSet);
        initialise(context, attributeSet);
    }

    public FontFitTextView(Context context, AttributeSet attributeSet, int defStyle)
    {
        super(context, attributeSet, defStyle);
        initialise(context, attributeSet);
    }

    private void initialise(Context context, AttributeSet attributeSet)
    {
        if(attributeSet!=null)
        {
            TypedArray styledAttributes = context.obtainStyledAttributes(attributeSet, R.styleable.FontFitTextView);
            maxFontSize = styledAttributes.getDimension(R.styleable.FontFitTextView_maxFontSize, MAX_FONT_SIZE_DEFAULT_VALUE);
            styledAttributes.recycle();
        }
        else
        {
            maxFontSize = MAX_FONT_SIZE_DEFAULT_VALUE;
        }

        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        //max size defaults to the initially specified text size unless it is too small
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth, int textHeight)
    {
        if (textWidth <= 0)
            return;
        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
        int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom();
        float hi = maxFontSize;
        float lo = 2;
//      final float threshold = 0.5f; // How close we have to be
        final float threshold = 1f; // How close we have to be

        mTestPaint.set(this.getPaint());

        Rect bounds = new Rect();

        while ((hi - lo) > threshold)
        {
            float size = (hi + lo) / 2;
            mTestPaint.setTextSize(size);

            mTestPaint.getTextBounds(text, 0, text.length(), bounds);

            if (bounds.width() >= targetWidth || bounds.height() >= targetHeight)
                hi = size; // too big
            else
                lo = size; // too small

//          if (mTestPaint.measureText(text) >= targetWidth)
//              hi = size; // too big
//          else
//              lo = size; // too small
        }
        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int height = getMeasuredHeight();
        refitText(this.getText().toString(), parentWidth, height);
        this.setMeasuredDimension(parentWidth, height);
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after)
    {
        refitText(text.toString(), this.getWidth(), this.getHeight());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        if (w != oldw)
        {
            refitText(this.getText().toString(), w, h);
        }
    }
}

ไฟล์ /res/values/attr.xml ที่สอดคล้องกัน:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="FontFitTextView">
        <attr name="maxFontSize" format="dimension" />
    </declare-styleable>

</resources>

ตัวอย่าง:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:res-auto="http://schemas.android.com/apk/res-auto"
    android:id="@+id/home_Layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:ignore="ContentDescription" >
...

 <com.<your_package>.FontFitTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:singleLine="true"
                    android:text="Sample Text"
                    android:textSize="28sp"
                    res-auto:maxFontSize="35sp"/>

...
</RelativeLayout>

หากต้องการใช้maxFontSizeคุณสมบัติใหม่อย่าลืมเพิ่มxmlns:res-auto="http://schemas.android.com/apk/res-auto"ตามที่แสดงในตัวอย่าง


ขออภัย แต่มันยังไม่สามารถใช้ได้กับทุกกรณี ฉันยังคิดว่ามันไม่สามารถจัดการหลายบรรทัดได้อย่างถูกต้อง
นักพัฒนา android

โอ้ .. คุณช่วยเล่าเรื่องที่ใช้ไม่ได้กับฉันได้ไหม (หลายสายไม่สนับสนุนคุณมีสิทธิ์)
ปาสกาล

หลายกรณี ฉันได้สร้างเครื่องมือทดสอบแบบสุ่มเพื่อพิสูจน์ว่ามันถูกต้อง นี่คือตัวอย่างหนึ่งความกว้างของมุมมอง: 317px ความสูง: 137px ข้อความ: "q7Lr" สิ่งที่ฉันเห็นคือ: tinypic.com/view.php?pic=2dv5yf9&s=6 นี่เป็นโครงการตัวอย่างที่ฉันได้ทำ: mega.co.nz/... ฉันคิดว่ามุมมองดังกล่าวควรรองรับหลายบรรทัดรองรับแบบอักษรทุกขนาดจัดการความสูงและไม่ใช่แค่ความกว้าง ... น่าเสียดายที่ไม่มีตัวอย่างใดที่ฉันพบว่าทำงานได้ดี
นักพัฒนา android

ตกลงแน่นอนไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์ ขอโทษ ไม่มีเวลาที่จะปรับปรุงในขณะนี้ .. หากคุณสามารถปรับปรุงได้อย่าลังเลที่จะโพสต์โซลูชันของคุณ
ปาสกาล

1
ฉันได้สร้างเธรดใหม่ที่แสดงการทดสอบของฉันโดยหวังว่าจะมีใครบางคนสามารถแก้ปัญหาได้ดี: stackoverflow.com/questions/16017165/…
นักพัฒนา Android

7

ฉันมีปัญหาเดียวกันและเขียนชั้นเรียนที่ดูเหมือนจะทำงานให้ฉัน โดยพื้นฐานแล้วฉันใช้เลย์เอาต์แบบคงที่เพื่อวาดข้อความในผืนผ้าใบแยกต่างหากและสร้างความจำจนกว่าฉันจะพบขนาดแบบอักษรที่พอดี คุณสามารถดูชั้นเรียนที่โพสต์ในหัวข้อด้านล่าง ฉันหวังว่ามันจะช่วย

ปรับสเกลข้อความอัตโนมัติให้พอดีภายในขอบเขต


6

ตอนนี้คุณสามารถทำได้โดยไม่ต้องมีห้องสมุดบุคคลที่สามหรือวิดเจ็ต มันสร้างไว้ใน TextView ใน API ระดับ 26 เพิ่มandroid:autoSizeTextType="uniform"ในของคุณTextViewความสูงและตั้งค่า นั่นคือทั้งหมดที่

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html

<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform" />

คุณยังสามารถใช้TextViewCompatเพื่อความเข้ากันได้


5

การปรับเปลี่ยนเล็กน้อยเพื่อ onMeasure:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    refitText(this.getText().toString(), parentWidth);
    this.setMeasuredDimension(parentWidth, parentHeight);
}

และการค้นหาแบบไบนารีบน refitText:

private void refitText(String text, int textWidth) 
{ 
    if (textWidth > 0) 
    {
        int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();         
        int trySize = (int)maxTextSize;
        int increment = ~( trySize - (int)minTextSize ) / 2;

        testPaint.setTextSize(trySize);
        while ((trySize > minTextSize) && (testPaint.measureText(text) > availableWidth)) 
        {
            trySize += increment;
            increment = ( increment == 0 ) ? -1 : ~increment / 2;
            if (trySize <= minTextSize) 
            {
                trySize = (int)minTextSize;
                break;
            }
            testPaint.setTextSize(trySize);
        }

        this.setTextSize( TypedValue.COMPLEX_UNIT_PX, trySize);
    }
}

3
แทนที่จะเป็นการค้นหาแบบไบนารีการปรับขนาดแบบธรรมดาทำได้ค่อนข้างดี: trySize *= availableWidth / measured_width(จากนั้นถูกจับไปที่ minTextSize)
Ted Hopp

5

ฉันพบว่าสิ่งต่อไปนี้ทำงานได้ดีสำหรับฉัน มันไม่วนซ้ำและมีทั้งความสูงและความกว้าง โปรดทราบว่าเป็นสิ่งสำคัญที่จะต้องระบุหน่วย PX เมื่อเรียกใช้ setTextSize บนมุมมอง ขอบคุณเคล็ดลับในการโพสต์ก่อนหน้านี้!

Paint paint = adjustTextSize(getPaint(), numChars, maxWidth, maxHeight);
setTextSize(TypedValue.COMPLEX_UNIT_PX,paint.getTextSize());

นี่คือกิจวัตรที่ฉันใช้ผ่านใน getPaint () จากมุมมอง สตริงอักขระ 10 ตัวที่มีอักขระ 'wide' ใช้เพื่อประเมินความกว้างโดยไม่ขึ้นกับสตริงจริง

private static final String text10="OOOOOOOOOO";
public static Paint adjustTextSize(Paint paint, int numCharacters, int widthPixels, int heightPixels) {
    float width = paint.measureText(text10)*numCharacters/text10.length();
    float newSize = (int)((widthPixels/width)*paint.getTextSize());
    paint.setTextSize(newSize);

    // remeasure with font size near our desired result
    width = paint.measureText(text10)*numCharacters/text10.length();
    newSize = (int)((widthPixels/width)*paint.getTextSize());
    paint.setTextSize(newSize);

    // Check height constraints
    FontMetricsInt metrics = paint.getFontMetricsInt();
    float textHeight = metrics.descent-metrics.ascent;
    if (textHeight > heightPixels) {
        newSize = (int)(newSize * (heightPixels/textHeight));
        paint.setTextSize(newSize);
    }

    return paint;
}

คุณรวมไว้ในเลย์เอาต์ xml ได้อย่างไร
AlikElzin-kilaka

รหัสนี้มีประโยชน์สำหรับการวางข้อความภายในมุมมองที่มีอยู่ลงในพื้นที่ขนาด จำกัด หรือคุณสามารถสร้างคลาสที่ได้รับของคุณเองจาก TextView และแทนที่ onMeasure ดังที่แสดงในโพสต์อื่น ๆ โดยตัวมันเองไม่สามารถใช้ในเลย์เอาต์
เกล็น

ตรวจสอบให้แน่ใจว่าคุณตรวจสอบขนาดของมุมมองหลังจากที่ถูกวาด การทำเช่นนี้ระหว่าง onCreate () เร็วเกินไป ฉันใช้ ViewTreeObserver เพื่อให้แน่ใจว่าการวัดนั้นถูกต้องในเวลาที่เหมาะสม
Scott Biggs

4

ทำงานร่วมกับการดัดแปลง

คุณต้องตั้งค่าขนาดมุมมองข้อความเช่นนี้เพราะมิฉะนั้น setTextSize ถือว่าค่าอยู่ในหน่วย SP:

setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);

และคุณต้องเพิ่มรหัสนี้อย่างชัดเจน

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    refitText(this.getText().toString(), parentWidth);
}

4

ใช้app:autoSizeTextType="uniform"สำหรับความเข้ากันได้แบบย้อนหลังเพราะ android:autoSizeTextType="uniform"ใช้งานได้ใน API ระดับ 26 ขึ้นไปเท่านั้น


2

ฉันใช้รูปแบบของโซลูชัน Dunni ด้านบน แต่รหัสเฉพาะนั้นใช้ไม่ได้สำหรับฉัน โดยเฉพาะอย่างยิ่งเมื่อพยายามใช้ชุดวัตถุ 'ระบายสี' เพื่อให้มีลักษณะของวัตถุ 'ระบายสี' ของมุมมองและจากนั้นเรียกใช้ measureText () จะไม่ส่งคืนค่าเดียวกันกับการเรียกวัตถุ 'ระบายสี' ของมุมมองโดยตรง บางทีอาจมีความแตกต่างบางอย่างในวิธีการตั้งค่ามุมมองของฉันที่ทำให้พฤติกรรมแตกต่างกัน

วิธีแก้ปัญหาของฉันคือการใช้ 'ระบายสี' ของมุมมองโดยตรงแม้ว่าอาจมีการลงโทษประสิทธิภาพในการเปลี่ยนขนาดแบบอักษรสำหรับมุมมองหลายครั้ง


2

ฉันพยายามปรับปรุงวิธีแก้ปัญหาที่ยอดเยี่ยมจาก speedplane และมากับสิ่งนี้ มันจัดการความสูงรวมถึงการตั้งค่าระยะขอบเพื่อให้ข้อความควรอยู่กึ่งกลางอย่างถูกต้องในแนวตั้ง

ฟังก์ชั่นนี้ใช้ฟังก์ชั่นเดียวกันเพื่อให้ได้ความกว้างเนื่องจากดูเหมือนว่าจะใช้งานได้ดีที่สุด แต่ใช้ฟังก์ชั่นที่แตกต่างกันเพื่อให้ได้ความสูง มีการแก้ไขบางอย่างที่ต้องทำ แต่ฉันคิดหาวิธีที่จะทำในขณะที่ดูน่าพอใจ

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialize();
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    private void initialize() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());

        //max size defaults to the initially specified text size unless it is too small
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth,int textHeight) 
    { 
        if (textWidth <= 0)
            return;
        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
        int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom();
        float hi = Math.min(targetHeight,100);
        float lo = 2;
        final float threshold = 0.5f; // How close we have to be

        Rect bounds = new Rect();

        mTestPaint.set(this.getPaint());

        while((hi - lo) > threshold) {
            float size = (hi+lo)/2;
            mTestPaint.setTextSize(size);
            mTestPaint.getTextBounds(text, 0, text.length(), bounds);
            if((mTestPaint.measureText(text)) >= targetWidth || (1+(2*(size+(float)bounds.top)-bounds.bottom)) >=targetHeight) 
                hi = size; // too big
            else
                lo = size; // too small
        }
        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX,(float) lo);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        int height = getMeasuredHeight();
        refitText(this.getText().toString(), parentWidth,height);
        this.setMeasuredDimension(parentWidth, height);
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
        refitText(text.toString(), this.getWidth(),this.getHeight());
    }

    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {

        if (w != oldw) {
            refitText(this.getText().toString(), w,h);
        }
    }

    //Attributes
    private Paint mTestPaint;
}


1

ฉันมีความเจ็บปวดในโครงการของฉันนานมากจนกระทั่งพบห้องสมุดนี้:

compile 'me.grantland:autofittextview:0.2.+'

คุณต้องเพิ่ม xml ตามความต้องการของคุณและทำเสร็จแล้ว ตัวอย่างเช่น:

<me.grantland.widget.AutofitTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:maxLines="2"
android:textSize="40sp"
autofit:minTextSize="16sp"
/>

0

แรงบันดาลใจจากผู้โพสต์ก่อนหน้านี้ฉันต้องการแบ่งปันวิธีแก้ปัญหาของฉัน มันทำงานร่วมกับตัวประกอบสเกลซึ่งใช้กับขนาดแบบอักษรก่อนหน้าเพื่อให้พอดีกับพื้นที่ว่าง นอกจากนี้เพื่อป้องกันพฤติกรรมที่ไม่คาดคิดของวิธี TextViews onDraw มันก็ดึงข้อความด้วยตัวเอง

public class FontFitTextView extends TextView {

    // How much of the available space should be used in percent.
    private static final float MARGINHEIGHT = 0.8f;
    private static final float MARGINWIDTH = 0.8f;

    private Paint paint;
    private int viewWidth;
    private int viewHeight;
    private float textHeight;
    private float textWidth;

    public FontFitTextView(Context c) {
        this(c, null);
    }

    public FontFitTextView(Context c, AttributeSet attrs) {
        super(c, attrs);
        initComponent();
    }

    // Default constructor override
    public FontFitTextView(Context c, AttributeSet attrs, int defStyle) {
        super(c, attrs, defStyle);
        initComponent();
    }

    private void initComponent() {
        paint = new Paint();
        paint.setTextSize(30);
        paint.setTextAlign(Align.CENTER);
        paint.setAntiAlias(true);
    }

    public void setFontColor(int c) {
        paint.setColor(c);
    }

    private void calcTextSize(String s, Canvas c) {

        float availableHeight = viewHeight;
        float availableWidth = viewWidth;

        // This value scales the old font up or down to match the available
        // space.
        float scale = 1.0f;

        // Rectangle for measuring the text dimensions
        Rect rect = new Rect();
        float oldFontSize = paint.getTextSize();

        // Calculate the space used with old font size
        paint.getTextBounds(s, 0, s.length(), rect);
        textWidth = rect.width();
        textHeight = rect.height();

        // find scale-value to fit the text horizontally
        float scaleWidth = 1f;
        if (textWidth > 0.0f) {
            scaleWidth = (availableWidth) / textWidth * MARGINWIDTH;
        }

        // find scale-value to fit the text vertically
        float scaleHeight = 1f;
        if (textHeight > 0.0f) {
            scaleHeight = (availableHeight) / textHeight * MARGINHEIGHT;
        }

        // We are always limited by the smaller one
        if (scaleWidth < scaleHeight) {
            scale = scaleWidth;
        } else {
            scale = scaleHeight;
        }

        // We apply the scale to the old font size to make it bigger or smaller
        float newFontSize = (oldFontSize * scale);
        paint.setTextSize(newFontSize);
    }

    /**
     * Calculates the origin on the Y-Axis (width) for the text in this view.
     * 
     * @return
     */
    private float calcStartDrawingPosX() {
        float left = getMeasuredWidth();
        float centerY = left - (viewWidth / 2);
        return centerY;
    }

    /**
     * Calculates the origin on the Y-Axis (height) for the text in this view.
     * 
     * @return
     */
    private float calcStartDrawingPosY() {
        float bottom = getMeasuredHeight();
        // The paint only centers horizontally, origin on the Y-Axis stays at
        // the bottom, thus we have to lift the origin additionally by the
        // height of the font.
        float centerX = bottom - (viewHeight / 2) + (textHeight / 2);
        return centerX;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        String text = getText().toString();
        if (text.length() > 0) {
            calcTextSize(text, canvas);
            canvas.drawText(text, calcStartDrawingPosX(),
                    calcStartDrawingPosY(), paint);
        }
    };

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        viewWidth = w;
        viewHeight = h;
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

0
/* get your context */
Context c = getActivity().getApplicationContext();

LinearLayout l = new LinearLayout(c);
l.setOrientation(LinearLayout.VERTICAL);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 0);

l.setLayoutParams(params);
l.setBackgroundResource(R.drawable.border);

TextView tv=new TextView(c);
tv.setText(" your text here");

/* set typeface if needed */
Typeface tf = Typeface.createFromAsset(c.getAssets(),"fonts/VERDANA.TTF");  
tv.setTypeface(tf);

// LayoutParams lp = new LayoutParams();

tv.setTextColor(Color.parseColor("#282828"));

tv.setGravity(Gravity.CENTER | Gravity.BOTTOM);
//  tv.setLayoutParams(lp);

tv.setTextSize(20);
l.addView(tv);

return l;

1
เพียงแค่อ่านรหัสของคุณฉันไม่คิดว่ามันจะใช้งานได้ โปรดจำไว้ว่าคำถามนั้นเกี่ยวกับการปรับขนาดตัวอักษรของมุมมองข้อความโดยอัตโนมัติเพื่อให้พอดีกับมุมมอง คุณตั้งค่าขนาดตัวอักษรคงที่
sulai

0

นี่ควรเป็นวิธีง่ายๆ:

public void correctWidth(TextView textView, int desiredWidth)
{
    Paint paint = new Paint();
    Rect bounds = new Rect();

    paint.setTypeface(textView.getTypeface());
    float textSize = textView.getTextSize();
    paint.setTextSize(textSize);
    String text = textView.getText().toString();
    paint.getTextBounds(text, 0, text.length(), bounds);

    while (bounds.width() > desiredWidth)
    {
        textSize--;
        paint.setTextSize(textSize);
        paint.getTextBounds(text, 0, text.length(), bounds);
    }

    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}

0

ขยาย TextView และแทนที่ onDraw ด้วยรหัสด้านล่าง มันจะรักษาอัตราส่วนของข้อความ แต่ปรับขนาดเพื่อเติมช่องว่าง คุณสามารถปรับเปลี่ยนรหัสเพื่อยืดหากจำเป็น

  @Override
  protected void onDraw(@NonNull Canvas canvas) {
    TextPaint textPaint = getPaint();
    textPaint.setColor(getCurrentTextColor());
    textPaint.setTextAlign(Paint.Align.CENTER);
    textPaint.drawableState = getDrawableState();

    String text = getText().toString();
    float desiredWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - 2;
    float desiredHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom() - 2;
    float textSize = textPaint.getTextSize();

    for (int i = 0; i < 10; i++) {
      textPaint.getTextBounds(text, 0, text.length(), rect);
      float width = rect.width();
      float height = rect.height();

      float deltaWidth = width - desiredWidth;
      float deltaHeight = height - desiredHeight;

      boolean fitsWidth = deltaWidth <= 0;
      boolean fitsHeight = deltaHeight <= 0;

      if ((fitsWidth && Math.abs(deltaHeight) < 1.0)
          || (fitsHeight && Math.abs(deltaWidth) < 1.0)) {
        // close enough
        break;
      }

      float adjustX = desiredWidth / width;
      float adjustY = desiredHeight / height;

      textSize = textSize * (adjustY < adjustX ? adjustY : adjustX);

      // adjust text size
      textPaint.setTextSize(textSize);
    }
    float x = desiredWidth / 2f;
    float y = desiredHeight / 2f - rect.top - rect.height() / 2f;
    canvas.drawText(text, x, y, textPaint);
  }

0

ฉันเขียนคลาสตัวช่วยสั้น ๆ ที่ทำให้มุมมองข้อความพอดีกับความกว้างและเพิ่ม "... " ที่จุดสิ้นสุดถ้าไม่สามารถทำข้อความขั้นต่ำได้

โปรดทราบว่าจะทำให้ข้อความมีขนาดเล็กลงจนกว่าจะพอดีหรือจนกว่าจะถึงขนาดข้อความขั้นต่ำ หากต้องการทดสอบที่มีขนาดใหญ่ให้ตั้งค่าขนาดข้อความเป็นจำนวนมากก่อนเรียกวิธีใช้

มันต้องใช้พิกเซลดังนั้นถ้าคุณใช้ค่าจากหรี่แสงคุณสามารถเรียกมันได้ดังนี้:


float minTextSizePx = getResources().getDimensionPixelSize(R.dimen.min_text_size);
float maxTextWidthPx = getResources().getDimensionPixelSize(R.dimen.max_text_width);
WidgetUtils.fitText(textView, text, minTextSizePx, maxTextWidthPx);

นี่คือคลาสที่ฉันใช้:


public class WidgetUtils {

    public static void fitText(TextView textView, String text, float minTextSizePx, float maxWidthPx) {
        textView.setEllipsize(null);
        int size = (int)textView.getTextSize();
        while (true) {
            Rect bounds = new Rect();
            Paint textPaint = textView.getPaint();
            textPaint.getTextBounds(text, 0, text.length(), bounds);
            if(bounds.width() < maxWidthPx){
                break;
            }
            if (size <= minTextSizePx) {
                textView.setEllipsize(TextUtils.TruncateAt.END);
                break;
            }
            size -= 1;
            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
        }
    }
}

สิ่งนี้รองรับข้อความหลายบรรทัดหรือไม่?
Roymunson

0

หากการเปลี่ยนรูปแบบเช่น allCaps มีการตั้งค่าวิธีการของเครื่องบินความเร็วเป็นรถ ฉันแก้ไขแล้วส่งผลให้รหัสต่อไปนี้ (ขออภัยชื่อเสียงของฉันไม่อนุญาตให้ฉันเพิ่มสิ่งนี้เป็นความคิดเห็นในการแก้ปัญหาของ speedplane):

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialise();
    }

    public FontFitTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialise();
    }

    private void initialise() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        //max size defaults to the initially specified text size unless it is too small
    }

    /* Re size the font so the specified text fits in the text box
     * assuming the text box is the specified width.
     */
    private void refitText(String text, int textWidth) 
    { 
        if (getTransformationMethod() != null) {
            text = getTransformationMethod().getTransformation(text, this).toString();
        }

        if (textWidth <= 0)
            return;
        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
        float hi = 100;
        float lo = 2;
        final float threshold = 0.5f; // How close we have to be

        mTestPaint.set(this.getPaint());

        while((hi - lo) > threshold) {
            float size = (hi+lo)/2;
            if(mTestPaint.measureText(text) >= targetWidth) 
                hi = size; // too big
            else
                lo = size; // too small
        }
        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int height = getMeasuredHeight();
        refitText(this.getText().toString(), parentWidth);
        this.setMeasuredDimension(parentWidth, height);
    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
        refitText(text.toString(), this.getWidth());
    }

    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        if (w != oldw) {
            refitText(this.getText().toString(), w);
      }
    }

    //Attributes
    private Paint mTestPaint;
}

0

ฉันไม่ทราบว่านี่เป็นวิธีที่ถูกต้องหรือไม่ bt มันทำงาน ... ใช้มุมมองของคุณและตรวจสอบ OnGlobalLayoutListener () และรับ linecount textview แล้วตั้ง textSize

 yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (textView.getLineCount()>=3) {
                textView.setTextSize(20);
            }else{
                //add somthing
              }
        }
    });

มันง่ายมากไม่กี่บรรทัดรหัส ..

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.