Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android上使TextView适合内部布局_Android_Textview_Spannable - Fatal编程技术网

在Android上使TextView适合内部布局

在Android上使TextView适合内部布局,android,textview,spannable,Android,Textview,Spannable,我有一个正方形的框架布局。我在布局中有一个TextView,用户可以选择增加/减少textSize。当文本足够大,可以填充整个框架布局时,我想限制文本增加选项。因此,如果我从25sp开始,当用户达到40sp并且TextView高度超过FrameLayout高度时,我需要恢复到39sp,并禁止进一步增加文本大小。TextView的源是一个Spanable 以下是我到目前为止是如何做到的 在增加按钮上,我只需为每个可跨越的片段设置一个大小(currentValue+1) 因为当我再次设置文本时,我不

我有一个正方形的框架布局。我在布局中有一个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);
}