2013-07-24 76 views
2

下面是我在堆棧溢出中的一些線程中找到的代碼,它減少了字體以適合文本視圖中的文本,但我想減少以及增加字體以適合文本在文本視圖中,這件事還沒有完成,搜索了很多,幫我增加字體大小以適應高度TextView Android

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); 
     } 
    } 

} 

回答

1

其實,有一些微不足道的錯誤。正如你所看到的,在你的代碼中檢查defaultTextSize,所以文本字體不能比它大,在對齊循環內還需要更正hi,因爲它會阻止比defaultTextSize更高的搜索大小。

所以,最終的代碼,這使得字體大而不限制將如下所示:

<RelativeLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

    <com.example.TestApp.FontFitTextView 
     android:layout_width="100dp" 
     android:layout_height="100dp" 
     android:id="@+id/textView" 
     android:layout_centerInParent="true" 
     android:text="This text is to be resized." /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:id="@+id/minus_button" 
     android:text="-10px" 
     android:padding="20dp" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_toRightOf="@id/minus_button" 
     android:id="@+id/plus_button" 
     android:text="+10px" 
     android:padding="20dp" /> 
</RelativeLayout> 

和活動:

public class MyActivity extends Activity { 

    private static final String TAG = "MyActivity"; 

    TextView mTextView = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Show the layout with the test view 
     setContentView(R.layout.main); 

     mTextView = (TextView) findViewById(R.id.textView); 

     final Button buttonPlus = (Button) findViewById(R.id.plus_button); 

     buttonPlus.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(final View v) { 
       changeTextViewSize(10); 
      } 
     }); 

     final Button buttonMinus = (Button) findViewById(R.id.minus_button); 

     buttonMinus.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(final View v) { 
       changeTextViewSize(-10); 
      } 
     }); 
    } 

    /** 
    * Changes text size by needed delta 
    * 
    * @param delta in px 
    */ 
    private void changeTextViewSize(final int delta) { 
     final ViewGroup.LayoutParams params = mTextView.getLayoutParams(); 

     params.height += delta; 
     params.width += delta; 

     mTextView.setLayoutParams(params); 
    } 
} 

public class FontFitTextView extends TextView { 

    // Attributes 
    private Paint mTestPaint; 
    /** 'Initial' text size */ 
    private float mDefaultTextSize; 

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

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

    private void initialize() { 
     mTestPaint = new Paint(); 
     mTestPaint.set(this.getPaint()); 
     mDefaultTextSize = 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(final String text, final 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(mDefaultTextSize); 

     // adjust text size using binary search for efficiency 
     float hi = Math.max(mDefaultTextSize, targetWidth); 
     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(final int widthMeasureSpec, final 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(final int w, final int h, final int oldw, final int oldh) { 
     if (w != oldw || h != oldh) { 
      refitText(this.getText().toString(), w); 
     } 
    } 
} 

你可以用下面的XML測試