2013-05-09 56 views
1

我想使TextViewEditTexttext size与其边界匹配。 我搜索了一下,发现下面的代码。所以,我创建了一个新的类代码如下:将文本向上缩放以适合TextView和EditText

package com.example.test; 


import android.content.Context; 
import android.text.Layout.Alignment; 
import android.text.StaticLayout; 
import android.text.TextPaint; 
import android.util.AttributeSet; 
import android.util.TypedValue; 
import android.widget.TextView; 


public class AutoResizeTextView extends TextView { 


     // Minimum text size for this text view 
     public static final float MIN_TEXT_SIZE = 20; 

     // Interface for resize notifications 
     public interface OnTextResizeListener { 
      public void onTextResize(TextView textView, float oldSize, float newSize); 
     } 

     // Our ellipse string 
     private static final String mEllipsis = "..."; 

     // Registered resize listener 
     private OnTextResizeListener mTextResizeListener; 

     // Flag for text and/or size changes to force a resize 
     private boolean mNeedsResize = false; 

     // Text size that is set from code. This acts as a starting point for resizing 
     private float mTextSize; 

     // Temporary upper bounds on the starting text size 
     private float mMaxTextSize = 0; 

     // Lower bounds for text size 
     private float mMinTextSize = MIN_TEXT_SIZE; 

     // Text view line spacing multiplier 
     private float mSpacingMult = 1.0f; 

     // Text view additional line spacing 
     private float mSpacingAdd = 0.0f; 

     // Add ellipsis to text that overflows at the smallest text size 
     private boolean mAddEllipsis = true; 

     // Default constructor override 
     public AutoResizeTextView(Context context) { 
      this(context, null); 
     } 

     // Default constructor when inflating from XML file 
     public AutoResizeTextView(Context context, AttributeSet attrs) { 
      this(context, attrs, 0); 
     } 

     // Default constructor override 
     public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
      mTextSize = getTextSize(); 
     } 

     /** 
     * When text changes, set the force resize flag to true and reset the text size. 
     */ 
     @Override 
     protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { 
      mNeedsResize = true; 
      // Since this view may be reused, it is good to reset the text size 
      resetTextSize(); 
     } 

     /** 
     * If the text view size changed, set the force resize flag to true 
     */ 
     @Override 
     protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
      if (w != oldw || h != oldh) { 
       mNeedsResize = true; 
      } 
     } 

     /** 
     * Register listener to receive resize notifications 
     * @param listener 
     */ 
     public void setOnResizeListener(OnTextResizeListener listener) { 
      mTextResizeListener = listener; 
     } 

     /** 
     * Override the set text size to update our internal reference values 
     */ 
     @Override 
     public void setTextSize(float size) { 
      super.setTextSize(size); 
      mTextSize = getTextSize(); 
     } 

     /** 
     * Override the set text size to update our internal reference values 
     */ 
     @Override 
     public void setTextSize(int unit, float size) { 
      super.setTextSize(unit, size); 
      mTextSize = getTextSize(); 
     } 

     /** 
     * Override the set line spacing to update our internal reference values 
     */ 
     @Override 
     public void setLineSpacing(float add, float mult) { 
      super.setLineSpacing(add, mult); 
      mSpacingMult = mult; 
      mSpacingAdd = add; 
     } 

     /** 
     * Set the upper text size limit and invalidate the view 
     * @param maxTextSize 
     */ 
     public void setMaxTextSize(float maxTextSize) { 
      mMaxTextSize = maxTextSize; 
      requestLayout(); 
      invalidate(); 
     } 

     /** 
     * Return upper text size limit 
     * @return 
     */ 
     public float getMaxTextSize() { 
      return mMaxTextSize; 
     } 

     /** 
     * Set the lower text size limit and invalidate the view 
     * @param minTextSize 
     */ 
     public void setMinTextSize(float minTextSize) { 
      mMinTextSize = minTextSize; 
      requestLayout(); 
      invalidate(); 
     } 

     /** 
     * Return lower text size limit 
     * @return 
     */ 
     public float getMinTextSize() { 
      return mMinTextSize; 
     } 

     /** 
     * Set flag to add ellipsis to text that overflows at the smallest text size 
     * @param addEllipsis 
     */ 
     public void setAddEllipsis(boolean addEllipsis) { 
      mAddEllipsis = addEllipsis; 
     } 

     /** 
     * Return flag to add ellipsis to text that overflows at the smallest text size 
     * @return 
     */ 
     public boolean getAddEllipsis() { 
      return mAddEllipsis; 
     } 

     /** 
     * Reset the text to the original size 
     */ 
     public void resetTextSize() { 
      if(mTextSize > 0) { 
       super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); 
       mMaxTextSize = mTextSize; 
      } 
     } 

     /** 
     * Resize text after measuring 
     */ 
     @Override 
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
      if(changed || mNeedsResize) { 
       int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight(); 
       int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop(); 
       resizeText(widthLimit, heightLimit); 
      } 
      super.onLayout(changed, left, top, right, bottom); 
     } 


     /** 
     * Resize the text size with default width and height 
     */ 
     public void resizeText() { 
      int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop(); 
      int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight(); 
      resizeText(widthLimit, heightLimit); 
     } 

     /** 
     * Resize the text size with specified width and height 
     * @param width 
     * @param height 
     */ 
     public void resizeText(int width, int height) { 
      CharSequence text = getText(); 
      // Do not resize if the view does not have dimensions or there is no text 
      if(text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) { 
       return; 
      } 

      // Get the text view's paint object 
      TextPaint textPaint = getPaint(); 

      // Store the current text size 
      float oldTextSize = textPaint.getTextSize(); 
      // If there is a max text size set, use the lesser of that and the default text size 
      float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize; 

      // Get the required text height 
      int textHeight = getTextHeight(text, textPaint, width, targetTextSize); 

      // Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes 
      while(textHeight > height && targetTextSize > mMinTextSize) { 
       targetTextSize = Math.max(targetTextSize - 2, mMinTextSize); 
       textHeight = getTextHeight(text, textPaint, width, targetTextSize); 
      } 

      // If we had reached our minimum text size and still don't fit, append an ellipsis 
      if(mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) { 
       // Draw using a static layout 
       StaticLayout layout = new StaticLayout(text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false); 
       // Check that we have a least one line of rendered text 
       if(layout.getLineCount() > 0) { 
        // Since the line at the specific vertical position would be cut off, 
        // we must trim up to the previous line 
        int lastLine = layout.getLineForVertical(height) - 1; 
        // If the text would not even fit on a single line, clear it 
        if(lastLine < 0) { 
         setText(""); 
        } 
        // Otherwise, trim to the previous line and add an ellipsis 
        else { 
         int start = layout.getLineStart(lastLine); 
         int end = layout.getLineEnd(lastLine); 
         float lineWidth = layout.getLineWidth(lastLine); 
         float ellipseWidth = textPaint.measureText(mEllipsis); 

         // Trim characters off until we have enough room to draw the ellipsis 
         while(width < lineWidth + ellipseWidth) { 
          lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString()); 
         } 
         setText(text.subSequence(0, end) + mEllipsis); 
        } 
       } 
      } 

      // Some devices try to auto adjust line spacing, so force default line spacing 
      // and invalidate the layout as a side effect 
      textPaint.setTextSize(targetTextSize); 
      setLineSpacing(mSpacingAdd, mSpacingMult); 

      // Notify the listener if registered 
      if(mTextResizeListener != null) { 
       mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize); 
      } 

      // Reset force resize flag 
      mNeedsResize = false; 
     } 

     // Set the text size of the text paint object and use a static layout to render text off screen before measuring 
     private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) { 
      // Update the text paint object 
      paint.setTextSize(textSize); 
      // Measure using a static layout 
      StaticLayout layout = new StaticLayout(source, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true); 
      return layout.getHeight(); 
     } 

    } 

但是我有什么从那里做,以使代码工作?这是我的代码和我的XML文件。我做错了什么,我该怎么做?

的Java:

package com.example.test; 

import android.app.Activity; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.net.Uri; 
import android.os.Bundle; 
import android.view.WindowManager; 
import android.widget.EditText; 
import android.widget.VideoView; 
import com.example.test.AutoResizeTextView; 

public class MainActivity extends Activity { 


    public VideoView vv; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // Set Fullscreen mode, overiding title and BATTERY 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // SCREEN NEVER GOES TO SLEEP MODE 

    //*** BACKGROUND MOVIE, LOOPING AND SETTING LOCAL PATH *** 
     vv = (VideoView) findViewById(R.id.videoView); 
     vv.setOnPreparedListener(new OnPreparedListener() { 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mp.setLooping(true); 
      } 
     }); 

     Uri url=Uri.parse("android.resource://" + getPackageName() +"/"+ R.raw.bubblessd); 
     vv.setVideoURI(url); 
     vv.start(); 
     vv.requestFocus(); 
     //*** BACKGROUND MOVIE, LOOPING AND SETTING LOCAL PATH *** 
    } 


final EditText myet = (EditText) findViewById(R.id.editText1); 
myet.resizeText(); 



} 

和XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    style="@style/AppTheme" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:fitsSystemWindows="true" 
    android:gravity="center" 
    android:soundEffectsEnabled="false" 
    tools:context=".MainActivity" > 


    <VideoView 
     android:id="@+id/videoView" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_alignParentTop="true" 
         android:layout_alignParentBottom="true" 
         android:layout_alignParentLeft="true" 
         android:layout_alignParentRight="true" /> 

    <LinearLayout 
     android:id = "@+id/main_menu_wrapper" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:gravity="center" 
        android:orientation="vertical" 
        android:weightSum="100"> 


     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="0dip" 
      android:layout_weight="20" 
      android:fitsSystemWindows="true" 
      android:gravity="center" 
      android:orientation="horizontal" 
      android:weightSum="100" > 


     <com.example.test.AutoResizeTextView 
      android:id="@+id/textView1" 
      android:layout_width="0dp" 
      android:layout_height="fill_parent" 
      android:layout_weight="20" 
      android:background="#55000000" 
      android:text="TextView" 
      /> 

        <EditText 
         android:id="@+id/editText1" 
         android:layout_width="0dp" 
         android:layout_height="fill_parent" 
         android:layout_weight="20" 
         android:background="#55000000" 
         android:inputType="text" 
         android:maxLength="10" 
         android:shadowColor="#000" 
         android:textColor="#FFFFFF" 
         android:textStyle="bold" > 

     </EditText> 
      </LinearLayout> 

     </LinearLayout> 



</RelativeLayout> 
+0

我试图让相同的代码工作几次,并总是放弃它,因为它不能很好地工作或引入其他错误/毛病行为。 – 2013-05-09 02:51:32

+0

至少你能告诉我如何使用它与我的主要Java代码?我必须从XML中调用它吗?如何?或者我如何从我的主要活动课程中调用它?我很喜欢编程。我有什么要写下来,以便我为我的TextView和EditText实现它,即使它无法正常工作? – user2347313 2013-05-09 05:06:23

回答

1

您已经正确地使用它。通过在您的XML中定义它,您告诉inflater使用该类。

如果您要访问它在Java中,把它像任何其他视图:

AutoResizeTextView textView = (AutoResizeTextView) findViewById(R.id.textView1); 
    textView.setText("Hello, user!"); 

它会表现得就像任何其他的文本视图,只是它应该自动调整大小的文本。

+0

感谢您的回复! – user2347313 2013-05-09 15:40:10