在Android上使TextView适合内部布局
我有一个正方形的框架布局。我在布局中有一个TextView,用户可以选择增加/减少textSize。当文本足够大,可以填充整个框架布局时,我想限制文本增加选项。因此,如果我从25sp开始,当用户达到40sp并且TextView高度超过FrameLayout高度时,我需要恢复到39sp,并禁止进一步增加文本大小。TextView的源是一个Spanable 以下是我到目前为止是如何做到的 在增加按钮上,我只需为每个可跨越的片段设置一个大小(currentValue+1) 因为当我再次设置文本时,我不知道文本视图的“真实”大小,所以我使用了在Android上使TextView适合内部布局,android,textview,spannable,Android,Textview,Spannable,我有一个正方形的框架布局。我在布局中有一个TextView,用户可以选择增加/减少textSize。当文本足够大,可以填充整个框架布局时,我想限制文本增加选项。因此,如果我从25sp开始,当用户达到40sp并且TextView高度超过FrameLayout高度时,我需要恢复到39sp,并禁止进一步增加文本大小。TextView的源是一个Spanable 以下是我到目前为止是如何做到的 在增加按钮上,我只需为每个可跨越的片段设置一个大小(currentValue+1) 因为当我再次设置文本时,我不
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)
}
缺点是增加文本->再次减少文本的可见操作。因此,用户将看到大约100毫秒的文本变大,然后恢复回来。
有没有一种处理此计算的好方法可以避免实际增加文本大小?您可以尝试以下方法:
textView.getLayoutParams.height = screen.getWidth();
textView.requestLayout();
我建议在实际更改文本大小之前,使用TextPaint和span类来测量文本。测量文本需要将其拆分为跨距。然后,您应该将跨距应用于TextPaint对象,并要求它提供文本块尺寸 这项任务相当复杂,因此如果有任何困难,请随时寻求更多帮助。我用来测量文本的代码很长,没有注释,因此我可能会将其发布到google代码中,以备不时之需。好了:
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
}
收到的所有答案都很好,但在我的例子中,我没有找到一种合适的方法来检测当应用Spanable时,我的TextView将如何实际包装文本。为了获得所需的结果,我只是在FrameLayout中添加了一个具有透明字体颜色的新TextView。首先,我将更改应用于这个不可见的文本视图,如果一切正常,我将更改传播到实际可见的文本视图。要进行一些微调,请阅读@Zielony的评论,从
绘制对象获取FontMatrics
,然后进行自定义计算。但此代码也应该可以正常工作。您的TextView
必须具有固定大小,否则足够的变量将始终为false。感谢您的详细回答,但我认为在使用spannable时它不起作用。可能对纯文本很有效。非常感谢你的回答,我要试试看它是否有效。我真的搞不懂。我的打赌是这样的:首先用所有属性/大小/字体重新创建Spanable,然后以某种方式将其绘制在与实际TextView大小相同的布局中,然后看看会发生什么。我认为拥有一个不可见的文本视图并首先应用所有值会更容易,如果一切正常,则应用于可见的文本视图。如何检测透明TextView
?我首先应用可扩展参数(文本大小、字体类型…)对于透明的TextView
,当呈现TextView后启动TextView.getViewTreeObserver()
时,我可以获得父布局上的实际高度/宽度/位置。根据这些值,我可以决定是否将参数应用于实际可见的TextView
。
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);
}