TextView.onDraw导致无限循环
问题描述:
我想要一个调整字体大小的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?
有没有办法阻止递归调用(如果这是发生了什么)?或者我应该以完全不同的方式进行探讨?
答
是否调用setTextSize()触发 无效化,这样的onDraw又被称为 ,不休?
是的,这可能是什么是hapening。如果你的setTextSize
take 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
}
}
}
答
这是幻想!奖励!我仍然在适应这个美好的世界,我们只能看源代码,看看发生了什么...
为了可能有兴趣的其他人的利益,我选择了使用快捷方式在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);
}
...和它的作品一种享受。谢谢!
太棒了!请参阅下面的完整回复。谢谢,克里斯 – ChrisV 2010-07-08 22:20:46