2013-02-26 54 views
2

我有一个正方形的FrameLayout。我在布局中有一个TextView,还有一个用于增加/减小textSize的选项。当文本足够大以填充整个FrameLayout时,我想限制文本增加选项。因此,如果我从25sp开始,当用户达到40sp并且TextView高度超过FrameLayout高度时,我需要恢复到39sp,并禁止进一步增加文本大小。 TextView的来源是可以跨越的。在Android上使TextView适合布局

这是我迄今为止做到的。

对于每个可跨越片段,增加按钮I只需setTextSize(currentValue + 1);

因为我不知道我的TextView的“真实”的大小时,我的setText再次,我已经使用

ViewTreeObserver vto = textView.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
    //here I have the real sizes of the textView and if the height is too big, I simply 
    setTextSize(currentValue - 1) 
} 

的缺点是增加文本的可视化操作 - >再次减少它。所以用户会看到100ms的文字变大,然后恢复原样。 是否有处理这种计算的好方法,所以我可以避免实际增加文本大小?

回答

0

所有收到的答案是伟大的,但对我来说我没有找到一个合适当应用Spannable时,检测我的TextView如何实际包裹文本的方法。为了得到我需要的结果,我只是在我的FrameLayout中添加了一个带有透明字体颜色的新TextView。首先,我将更改应用到这个不可见的TextView,如果一切正常,我将更改传播到实际可见的TextView。

+0

如何检测透明的'TextView',一切工作正常? – 2013-03-05 19:21:39

+0

我首先将可扩展参数(文本大小,字体类型..)应用于透明的“TextView”,并且在呈现TextView之后启动了“textView.getViewTreeObserver()”时,我可以得到实际的高度/宽度/位置在父母的布局。根据这些值,我可以决定是否将参数应用于实际可见的“TextView”。 – Alin 2013-03-05 20:46:11

0

你可以尝试这样的事:

textView.getLayoutParams.height = screen.getWidth(); 
textView.requestLayout(); 
2

我会建议使用TextPaint和跨度类实际改变大小之前来衡量你的文字。测量文本需要将其分割为跨度。然后,您应该将这些跨度应用于TextPaint对象并请求它为文本块尺寸。

http://developer.android.com/reference/android/text/TextPaint.html http://developer.android.com/reference/android/graphics/Paint.FontMetrics.html http://developer.android.com/reference/android/text/style/CharacterStyle.html

的任务是相当复杂的,所以在任何麻烦的情况下随时要求更多的帮助。我用来测量文字的代码很长且没有注释,所以我可能会将其发布到谷歌代码以防万一需要。

+0

非常感谢您的回答,我会试试看看它是否有效。 – Alin 2013-02-26 11:44:03

+0

我真的搞不清楚。我的打赌会是这样的:首先重新创建具有所有属性/大小/字体的spannable,然后以与我的实际TextView相同大小的布局绘制它,并查看会发生什么。我认为有一个不可见的TextView会更容易,并首先将所有的值应用于它,如果一切正常,则应用于可见的值。 – Alin 2013-02-28 19:30:44

1

你去那里:

TextView tv = (TextView) findViewById(R.id.tv); 
String myText = tv.getText().toString(); 
char[] array = myText.toCharArray(); 
Paint paint = tv.getPaint(); 
Rect textBound = new Rect(); 
paint.getTextBounds(array, 0, array.length, textBound); 
boolean enough = tv.getHeight() <= textBound.height() 
      || tv.getWidth() <= textBound.width(); 
if(enough){ 
    // don't increase size further 
}else{ 
// increase size 
} 

对于动画,你可以做财产以后这样的:

final float proposed = tv.getTextSize() + 10; 
final float orignal = tv.getTextSize(); 

if (enough) { 
    ObjectAnimator 
       .ofFloat(this, "textSize", orignal, proposed, orignal) 
       .setDuration(1000).start(); 
} else { 
    ObjectAnimator.ofFloat(this, "textSize", orignal, proposed) 
       .setDuration(500).start(); 
} 


@SuppressWarnings("unused") 
private void setTextSize(float val) { 
    tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, val); 
} 
+0

对于一些微调阅读@ Zielony的评论,从'Paint'对象获得'FontMatrics'并且做你自定义的计算。但是这个代码也应该可以正常工作。 – 2013-02-26 11:32:41

+0

你的'TextView'必须是固定的大小,否则'enough'变量将始终为假。 – 2013-02-26 11:38:32

+0

感谢您的详细解答,但我认为它在使用spannable时不起作用。可能对纯文本很有用。 – Alin 2013-02-28 19:40:21