2010-07-08 188 views
1

我想要一个调整字体大小的TextView,以便视图中的文本将自动扩展(或缩小)以填充视图的全部宽度。我想我也许可以做到这一点通过创建一个定制的TextView其覆盖的onDraw()如下:TextView.onDraw导致无限循环

public class MaximisedTextView extends TextView { 
    // (calls to super constructors here...) 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     TextPaint textPaint = this.getPaint(); 
     Rect bounds = new Rect(); 

     String text = (String)this.getText(); // current text in view 
     float textSize = this.getTextSize(); // current font size 
     int viewWidth = this.getWidth() - this.getPaddingLeft() - this.getPaddingRight(); 
     textPaint.getTextBounds(text, 0, text.length(), bounds); 
     int textWidth = bounds.width(); 

     // reset font size to make text fill full width of this view 
     this.setTextSize(textSize * viewWidth/textWidth); 
    } 
} 

然而,这将应用到一个死循环(与文本的大小不断增长,每一次稍有萎缩!),所以我很清楚这是错误的。对setTextSize()的调用是否会触发无效,从而无休止地再次调用onDraw?

有没有办法阻止递归调用(如果这是发生了什么)?或者我应该以完全不同的方式进行探讨?

回答

3

是否调用setTextSize()触发 无效化,这样的onDraw又被称为 ,不休?

是的,这可能是什么是hapening。如果你的setTextSizetake a look of the source code你会看到,它会调用这个方法:

private void setRawTextSize(float size) { 
    if (size != mTextPaint.getTextSize()) { 
     mTextPaint.setTextSize(size); 

     if (mLayout != null) { 
      nullLayouts(); 
      requestLayout(); 
      invalidate(); // yeahh... invalidate XD 
     } 
    } 
} 

所以,如果你正在做重写onDraw方法的辛勤工作,你为什么不直接使用一些的drawText方法Canvas课?

+0

太棒了!请参阅下面的完整回复。谢谢,克里斯 – ChrisV 2010-07-08 22:20:46

3

这是幻想!奖励!我仍然在适应这个美好的世界,我们只能看源代码,看看发生了什么...

为了可能有兴趣的其他人的利益,我选择了使用快捷方式在TextPaint.setTextSize()方法,而不是钻研Canvas.drawText(),所以我的onDraw()现在是如下:

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    TextPaint textPaint = this.getPaint(); 
    Rect bounds = new Rect(); 

    String text = (String)this.getText(); 
    float textSize = this.getTextSize(); 
    int viewWidth = this.getWidth() - this.getPaddingLeft() - this.getPaddingRight(); 
    textPaint.getTextBounds(text, 0, text.length(), bounds); 
    int textWidth = bounds.width(); 

    float newTextSize = (float)Math.floor(textSize * viewWidth/textWidth); 

    // note: adapted from TextView.setTextSize(), removing invalidate() call: 

    // get the raw text size... 
    Context c = getContext(); 
    Resources r = c==null ? Resources.getSystem() : c.getResources(); 
    int unit = TypedValue.COMPLEX_UNIT_SP; 
    float rawSize = TypedValue.applyDimension(unit, newTextSize, r.getDisplayMetrics()); 

    // ... and apply it directly to the TextPaint 
    textPaint.setTextSize(rawSize); 
} 

...和它的作品一种享受。谢谢!