Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.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
Java android canvas drawText从宽度设置字体大小?_Java_Android_Android Canvas - Fatal编程技术网

Java android canvas drawText从宽度设置字体大小?

Java android canvas drawText从宽度设置字体大小?,java,android,android-canvas,Java,Android,Android Canvas,我想使用在画布上绘制一定宽度的文本。drawtext 例如,无论输入文本是什么,文本的宽度应始终为400px 如果输入文本较长,则会减小字体大小;如果输入文本较短,则会相应增大字体大小。请尝试以下操作: /** * Retrieve the maximum text size to fit in a given width. * @param str (String): Text to check for size. * @param maxWidth (float): Maximum a

我想使用
画布上绘制一定宽度的文本。drawtext

例如,无论输入文本是什么,文本的宽度应始终为
400px

如果输入文本较长,则会减小字体大小;如果输入文本较短,则会相应增大字体大小。

请尝试以下操作:

/**
 * Retrieve the maximum text size to fit in a given width.
 * @param str (String): Text to check for size.
 * @param maxWidth (float): Maximum allowed width.
 * @return (int): The desired text size.
 */
private int determineMaxTextSize(String str, float maxWidth)
{
    int size = 0;       
    Paint paint = new Paint();

    do {
        paint.setTextSize(++ size);
    } while(paint.measureText(str) < maxWidth);

    return size;
} //End getMaxTextSize()
/**
*检索适合给定宽度的最大文本大小。
*@param str(字符串):用于检查大小的文本。
*@param maxWidth(float):允许的最大宽度。
*@return(int):所需的文本大小。
*/
私有int determineMextSize(字符串str,float maxWidth)
{
int size=0;
油漆=新油漆();
做{
油漆。setTextSize(++尺寸);
}while(paint.measureText(str)
这里有一个更有效的方法:

/**
 * Sets the text size for a Paint object so a given string of text will be a
 * given width.
 * 
 * @param paint
 *            the Paint to set the text size for
 * @param desiredWidth
 *            the desired width
 * @param text
 *            the text that should be that width
 */
private static void setTextSizeForWidth(Paint paint, float desiredWidth,
        String text) {

    // Pick a reasonably large value for the test. Larger values produce
    // more accurate results, but may cause problems with hardware
    // acceleration. But there are workarounds for that, too; refer to
    // http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
    final float testTextSize = 48f;

    // Get the bounds of the text, using our testTextSize.
    paint.setTextSize(testTextSize);
    Rect bounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), bounds);

    // Calculate the desired size as a proportion of our testTextSize.
    float desiredTextSize = testTextSize * desiredWidth / bounds.width();

    // Set the paint for that size.
    paint.setTextSize(desiredTextSize);
}
然后,您需要做的就是
setTextSizeForWidth(paint,400,str)(400为问题中的示例宽度)

为了获得更高的效率,您可以将
Rect
设置为静态类成员,避免每次实例化它。但是,这可能会带来并发性问题,并且可能会阻碍代码的清晰性。

看起来不错,但对我来说不起作用,我需要获得视图中可能绘制的最大文本大小,但这种方法取决于您设置的第一个文本大小,每次你设置不同的尺寸,你会得到不同的结果,不能说这是正确的答案在每种情况下

所以我尝试了另一种方法:

private float calculateMaxTextSize(String text, Paint paint, int maxWidth, int maxHeight) {
    if (text == null || paint == null) return 0;
    Rect bound = new Rect();
    float size = 1.0f;
    float step= 1.0f;    
    while (true) {
        paint.getTextBounds(text, 0, text.length(), bound);
        if (bound.width() < maxWidth && bound.height() < maxHeight) {
            size += step;
            paint.setTextSize(size);
        } else {
            return size - step;
        }
    }
}
private float calculateMaxSize(字符串文本、油漆、int-maxWidth、int-maxHeight){
if(text==null | | paint==null)返回0;
Rect-bound=新的Rect();
浮子尺寸=1.0f;
浮动步长=1.0f;
while(true){
paint.getTextBounds(text,0,text.length(),bound);
if(bound.width()

很简单,我增加文本大小,直到文本矩形边界的尺寸足够接近
maxWidth
maxHeight
,以减少循环重复,只需将
step
更改为更大的值(精度与速度),也许这不是实现这一点的最佳方法,但它是有效的。

只是出于好奇,为什么要返回
尺寸/2
?我想有一个很好的理由我现在想不起来,但是
size-1
对我来说更有意义:/告诉你真相,我记不清了。我知道我试过使用
-1
,但认为我没有得到我想要的东西。这不起作用。。我正在做的是将maxwidth设置为我手机的屏幕宽度,即560px,但当我设置它时,它不适合屏幕,它比这个大得多。字体大小并没有相应地改变。哦,现在我正在传递不同的字符串值并绘制不同的字符串。我的错。它与
size
而不是
size/2
一起工作。请编辑您的答案。这里面有一个bug。您不处理str没有字符或只有空格的情况。你因为它而永远迭代。将此添加为第一行<代码>如果(str==null | | str.trim().length()==0)返回0啊,见鬼!:-)很高兴能帮上忙。我能知道你从哪里选的400吗?因为我试过你的方法,但我的一些文本会从画布上消失,比如一两个字母。我试过bitmap.getwidth(),它更好,但仍然不够有效。@Chisko:当然,因为我从1997年开始编写Java,我想它是合适的。☺ 当一个方法是静态的时,无论类有多少个实例,每个JVM都只有一个副本。但对于非静态方法,类的每个实例都有一个副本,因此可以有多个局部变量副本,我相信字节码本身也是如此。我承认这在你的Android应用程序中可能是相当学术的,如果你只创建了一个实例,不管你把代码放在哪个类中,但这是一个好习惯。我强烈推荐布洛赫的书以获取更多信息。更直接地回答你的问题:还有谁会使用这种方法?类的其他实例。假设您编写了一个小部件并将
setTextSizeForWidth
放入其中,您的应用程序就有三个这样的小部件。如果您的小部件的类使此方法成为静态的,则将有一个副本。如果没有,就有三个。三个副本一次只能使用一个方法,但每次都会为两个
浮点
分配新内存,直到垃圾回收后才会释放。同样,在这种情况下是次要的,但对于较大对象的较大集合,它可能会很快导致问题。这与@slybloty的答案具有相同的效率问题。我也不明白你在我的解决方案中遇到的问题;关键是,不同的宽度会有不同的文本大小。如果我记得right
float desiredTextSize=testTextSize*desiredWidth/bounds.width(),那么你能留下一条注释,并举例说明它没有返回正确大小的参数吗?老实说,你的解决方案是有效的,但不是我所期望的
返回一个可接受的值,但不一定是最大大小,毫无疑问,您的解决方案更有效,但我认为结果与
所需的宽度
有很大的关系,而不是像我所需要的那样精确,因为您试图适应最大高度和最大宽度?尝试
float desiredTextSize=testTextSize*Math.min(desiredWidth/bounds.width(),desiredHeight/bounds.height())
。在任何情况下,都要注意解决方案中的整数;它们将导致浮点值只包含整数值,而整数值可能没有您需要的那么精确。