如何根据视图最大尺寸自动调整多行 TextView 上的文本大小? [英] How to auto-adjust text size on a multi-line TextView according to the view max dimensions?

查看:38
本文介绍了如何根据视图最大尺寸自动调整多行 TextView 上的文本大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一种在 textview 中自动调整文本的方法.通过搜索,我找到了许多解决方案,例如:

I've been searching for a way of auto fit a text inside a textview. Through my search I've found many solutions like:

但像许多其他人一样,这些并不能解决我的问题.当我们使用带有多行的 TextView 时,它们无法按预期工作.

But like many others these doesn't solve my problem. They don't work as expected when we use a TextView with multiline.

基本上我的目标是这个:

Basically my goal is this one:

如您所见,文本根据宽度、高度调整大小并注意换行,创建多行文本视图.还可以更改字体.

As you can see, the text resizes based on width, height and also pays attention to the line break, creating a multi-line textview. Also be able to change the typeface.

我解决这个问题的一个想法是这样的:

One of my ideas to solve this was something like this:

int size = CONSTANT_MAX_SIZE;
TextView tv = (TextView) findViewById(R.id.textview1)
while(Math.abs(tv.getMeasuredHeight()) >= TEXTVIEW_MAX_HEIGHT) {
    size--;
    tv.setTextSize(size);
    tv.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
    i++;
}

CONSTANT_MAX_SIZE 是一个常量,定义了字体的最大尺寸(TextView 中的 textsize 属性)

CONSTANT_MAX_SIZE is a constant that defines the max size of the font (textsize propriety in a TextView)

TEXTVIEW_MAX_HEIGHT 是一个常量,它定义了 textview 可以拥有的最大尺寸.

TEXTVIEW_MAX_HEIGHT is a constant that defines the max size that the textview can have.

每次更改文本视图中的文本时都会调用它.

This was called every time the text in the textview was changed.

textview xml 是这样的:

The textview xml was something like this:

<TextView
     android:id="@+id/textview1"
     android:layout_width="200dp"
     android:layout_height="wrap_content"
     android:singleLine="false"
     android:inputType="textMultiLine"
     android:text=""
     android:textSize="150sp" />

由于在 XML 中宽度会受到限制,因此只需要考虑视图的高度,因为调整它 android 会在需要时自动创建多行.

Since the width would be limited in the XML, only the height of the view needs to be considered since adjusting it android would automatically create a multiline when needed.

虽然这是一个潜在的解决方案,但效果并不理想(远非如此),并且不支持缩小尺寸(当您删除文本时).

Although this is a potential solution isn't working perfectly (far from it) and it doesn't support resize down (when you delete text).

有什么建议和/或想法吗?

Any sugestions and/or ideas?

推荐答案

在等待这个问题的可能解决方案时,我一直在尝试并试图弄清楚.

While I waited for a possible solution to this question, I have been experimenting and trying to figure it out.

这个问题最接近的解决方案是基于paint方法.

The closest solution to this problem was based in a method from paint.

基本上,paint 有一个名为breaktext"的方法:

Basically paint has a method called 'breaktext' which:

public int breakText (CharSequence text, int start, int end, booleanmeasureForwards, float maxWidth, float[] measureWidth)

public int breakText (CharSequence text, int start, int end, boolean measureForwards, float maxWidth, float[] measuredWidth)

在 API 级别 1 中添加

Added in API level 1

测量文本,如果测量的宽度超过则提前停止最大宽度.返回测量的字符数,如果测量宽度不为空,返回测量的实际宽度.

Measure the text, stopping early if the measured width exceeds maxWidth. Return the number of chars that were measured, and if measuredWidth is not null, return in it the actual width measured.

我将它与paint 'getTextBounds' 结合起来:

I combine that with paint 'getTextBounds' which:

public void getTextBounds (String text, int start, int end, Rect bounds)

public void getTextBounds (String text, int start, int end, Rect bounds)

在 API 级别 1 中添加

Added in API level 1

返回边界(由调用者分配)包围所有 >字符的最小矩形,隐含原点位于 (0,0).

Return in bounds (allocated by the caller) the smallest rectangle that encloses all of the >characters, with an implied origin at (0,0).

所以现在我可以获得适合给定宽度的字符数和这些字符的高度.

So now I can obtain the number of chars that fit in a given width and the height of those chars.

使用一段时间,您可以继续从要测量的字符串中移动删除字符并获取行数(通过使用 while(index < string.length))并将其乘以在 getTextBounds 中获得的高度.

Using a while you can keep moving the removing chars from the string you want to measure and obtain the number of lines (by using a while(index < string.length)) and multiply that by the height obtained in the getTextBounds.

此外,您必须为每两行添加一个可变高度,表​​示行之间的空间(不计入 getTextBounds).

Additionally you will have to add a variable height for each two lines that represent the space between the lines (which is not counted in the getTextBounds).

作为示例代码,了解多行文本高度的函数如下所示:

As an example code, the function to know the height of a multiple line text is something like this:

public int getHeightOfMultiLineText(String text,int textSize, int maxWidth) {
    paint = new TextPaint();
    paint.setTextSize(textSize);
    int index = 0;
    int linecount = 0;
    while(index < text.length()) {
        index += paint.breakText(text,index,text.length,true,maxWidth,null);
        linecount++;
    }

    Rect bounds = new Rect();
    paint.getTextBounds("Yy", 0, 2, bounds);
    // obtain space between lines
    double lineSpacing = Math.max(0,((lineCount - 1) * bounds.height()*0.25)); 

    return (int)Math.floor(lineSpacing + lineCount * bounds.height());

注意:maxWidth 变量以像素为单位

然后您将不得不在一段时间内调用此方法以确定该高度的最大字体大小.示例代码如下:

Then you will have to call this method inside a while to determine what is the max font size for that height. An example code would be:

textSize = 100;
int maxHeight = 50;
while(getHeightOfMultiLineText(text,textSize,maxWidth) > maxHeight)
  textSize--;

不幸的是,这是我能够实现上述图像方面的唯一(据我所知)方式.

Unfortunately this was the only (as far as I know) way I was able to achieve the aspect from the images above.

希望这对任何试图克服这一障碍的人有所帮助.

Hope this can be of help to anyone trying to overcome this obstacle.

这篇关于如何根据视图最大尺寸自动调整多行 TextView 上的文本大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆