【问题标题】:Draw text inside a filled rectangle using Canvas Android使用 Canvas Android 在填充的矩形内绘制文本
【发布时间】:2013-03-14 14:48:00
【问题描述】:

如何使用 Canvas Android 绘制具有指定边界的填充矩形并在该矩形文本内绘制?我试过了

mPaint.setColor(Color.GREEN);
canvas.drawText(mText, x, y, mPaint);
mPaint.setColor(Color.BLACK);
canvas.drawRect(x, y, x + w, y + h, mPaint);

但文本不在该矩形内。有没有朋友可以告诉我如何在考虑到文本大小的情况下绘制一个围绕指定文本的矩形?

【问题讨论】:

    标签: android canvas view drawing


    【解决方案1】:

    这里我硬编码了 x 和 y 值。您可以更改它们

            mpaint= new Paint();
            mpaint.setColor(Color.RED);
            mpaint.setStyle(Style.FILL);
            paint2= new Paint();
            paint2.setColor(Color.GREEN);
            paint2.setTextSize(50);  //set text size
            float w = paint2.measureText(s)/2;
            float textSize = paint2.getTextSize();
    
    
            @Override
            protected void onDraw(Canvas canvas) {
                paint2.setTextAlign(Paint.Align.CENTER);
                canvas.drawRect(300-w, 300 - textsize, 300 + w, 300, mpaint);
                canvas.drawText(s, 300, 300 ,paint2); //x=300,y=300    
            }
    

    编辑:

    onDraw 中调用measureText 是个坏主意。您可以在 onDraw 之外执行此操作。

    还有一个关于性能的视频,以及为什么您应该避免在onDraw 中分配。 https://www.youtube.com/watch?v=HAK5acHQ53E

    生成的快照

    【讨论】:

    • 抱歉忘了说,矩形应该只覆盖文本区域,位置和文本大小可能会动态变化。取决于我要绘制矩形的文本大小和长度??
    • 为什么绘制的矩形中有一个空白区域?默认情况下drawtext使用一些顶部填充,如果是如何避免这种情况?
    • @AlexanderFarber 一定是复制粘贴错误。我从编辑器中复制了代码。我忘记了,把它拿出来。
    • onDraw() 中调用measureText() 仍然不好,两次。
    • @AlexanderFarber 同意我很早就回答了这个问题,我会尽快纠正这个问题。
    【解决方案2】:

    如果您必须将文本直接居中,则可以使用此代码

        mpaint= new Paint();
        mpaint.setColor(Color.RED);
        mpaint.setStyle(Style.FILL);
        paint2= new Paint();
        paint2.setColor(Color.GREEN);
        paint2.setTextSize(50);  //set text size
        float w = paint2.measureText(s)/2;
        float textSize = paint2.getTextSize();
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            paint2.setTextAlign(Paint.Align.CENTER);
            Rect rect = new Rect(300-w, 300 - textsize, 300 + w, 300);
            canvas.drawRect(rect, mpaint);
            canvas.drawText(s, rect.centerX(), rect.centerY() ,paint2); // center text inside rect
        }
    

    【讨论】:

      【解决方案3】:

      对于这个特定的查询,这可能会很晚,但我认为很多人会发现这个答案很有用。因此,任何 CustomView 的 Canvas 的问题在于,您可以获取特定文本的宽度,但获取文本的高度并不容易。此外,如果您将canvas.drawText(....) 与简单的Paint 对象一起使用,则无法绘制多行文本。因此,请在您的 onDraw() 方法中使用以下代码。

      String displayText = "Hello World";
      int mainTextPositionX = getWidth() / 2 ;
      int mainTextPositionY = getHeight() / 2;
      
      StaticLayout textStaticLayout;
      TextPaint textPaint;
      textPaint = new TextPaint();
      textPaint.setTextAlign(Paint.Align.CENTER);
      textPaint.setColor(Color.BLUE);
      textPaint.setAntiAlias(true);
      textPaint.setTextSize(convertDpToPixel(30, context));
      textPaint.setTextAlign(Paint.Align.CENTER);
      highlightedRectPaint = new Paint();
      
      highlightedRectPaint.setStrokeWidth(12);
      highlightedRectPaint.setStyle(Paint.Style.STROKE);
      highlightedRectPaint.setColor(Color.RED);
      highlightedRectPaint.setAntiAlias(true);
      
      if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
              textStaticLayout = StaticLayout
                      .Builder
                      .obtain(displayText, 0, displayText.length(), textPaint, (int) textPaint.measureText(displayText))
                      .build();
          }else{
              textStaticLayout = new StaticLayout(
                      displayText, textPaint, (int)textPaint.measureText(displayText), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
          }
      
          Rect highlightedTextBorderRect = new Rect();
          highlightedTextBorderRect.top = mainTextPositionY-20;
          highlightedTextBorderRect.left = mainTextPositionX- 
          ((int)textPaint.measureText(displayText)/2)-20;
          highlightedTextBorderRect.right = mainTextPositionX+ 
          ((int)textPaint.measureText(displayText)/2) + 20;
          highlightedTextBorderRect.bottom = mainTextPositionY+ 
          (int)textStaticLayout.getHeight()+20;
      
          canvas.save();
          canvas.translate(mainTextPositionX, mainTextPositionY);
          textStaticLayout.draw(canvas);
          canvas.restore();
      
          canvas.drawRect(highlightedTextBorderRect,highlightedRectPaint);
      

      只需确保在draw() 方法之外声明所有对象和变量。这将在多行支持的文本周围绘制一个矩形轮廓。如果您希望矩形有填充,则只需使用 highlightedRectPaint 并更改 setStyle(Paint.Style.FILL)。希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 2018-06-30
        • 1970-01-01
        • 1970-01-01
        • 2015-01-11
        • 2021-06-30
        • 1970-01-01
        相关资源
        最近更新 更多