【问题标题】:android canvas draw text in the triangleandroid canvas在三角形中绘制文本
【发布时间】:2017-04-24 05:33:20
【问题描述】:

在这张图片中,我希望文本完全位于带有CYAN 颜色的三角形中。
我创建了自己的ImageView

public class BookImageView extends android.support.v7.widget.AppCompatImageView {

private static final Float DISCOUNT_SIDE_SIZE = 0.33333F;

private Bitmap bitmap;

private Paint drawPaint = new Paint();
private Paint trianglePaint = new Paint();

{
    trianglePaint.setColor(Constants.DISCOUNT_COLOR);
    trianglePaint.setStyle(Paint.Style.FILL);
    trianglePaint.setShadowLayer(10.0f, 10.0f, 10.0f, Color.parseColor("#7f000000"));
    trianglePaint.setAntiAlias(true);

    drawPaint.setColor(Color.BLACK);
    drawPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
    drawPaint.setShadowLayer(1f, 0f, 1f, Color.BLACK);
}

// Constractors ...    

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (bitmap != null) {
        Bitmap tempBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565);
        Canvas tempCanvas = new Canvas(tempBitmap);
        tempCanvas.drawBitmap(bitmap, 0, 0, null);

        Path path = new Path();
        path.setFillType(Path.FillType.EVEN_ODD);

        float size = bitmap.getWidth() * DISCOUNT_SIDE_SIZE;

        path.lineTo(size, 0);
        path.lineTo(0, size);
        path.lineTo(0, 0);
        path.close();

        tempCanvas.drawPath(path, trianglePaint);

        float scale = getResources().getDisplayMetrics().density;

        drawPaint.setTextSize((int) (14 * scale));

        Rect textBounds = new Rect();
        drawPaint.getTextBounds("50%", 0, "50%".length(), textBounds);
        int x = (int) (size / 2) - textBounds.width() / 2;
        int y = (int) (size / 2) - textBounds.height() / 2;

        tempCanvas.save();
        tempCanvas.rotate(-45, x, y);
        tempCanvas.drawText("50%", x, y, drawPaint);
        tempCanvas.restore();

        setImageDrawable(new BitmapDrawable(getContext().getResources(), tempBitmap));
    }
}

@Override
public void setImageBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
    invalidate();
}

}

我能做些什么来解决这个问题?

【问题讨论】:

  • 缩小文字大小?
  • 尝试绘制一个未旋转的三角形,然后将整个视图旋转 45 度
  • @SunnyKumarAditya 感谢您的回答。但没有工作
  • 你能分享代码和结果快照吗?当我有时间时会深入挖掘。

标签: android canvas android-custom-view android-drawable android-bitmap


【解决方案1】:

你可以试试这样的

1) 测量文本的宽度 使用measureText

2) 从您要绘制的点计算剩余的绘制宽度

3) 现在,您可以根据用例缩短文本长度或根据需要缩放文本

    int textWidthRequired = (int) drawPaint.measureText(textToDraw);
    int widthRemainingToDraw = totalWidth/2 - textDrawX;
    if(textWidthRequired > widthRemainingToDraw){
        //handling 
    }
    // draw text
   tempCanvas.drawText(textToDraw,textDrawX, textDrawY, drawPaint);

【讨论】:

    【解决方案2】:

    根据您希望文本的高度,您可以使用相似三角形的属性首先确定文本的最大宽度。在您的情况下,大小 = 三角形的底边,大小 = 三角形的高度/高度。让我们定义两个变量: 更正:高度不等于基地。您需要计算高度才能使用以下解决方案。

    float triangleBase = size; // triangle base
    float triangleAltitude = size; // Calculate this.
    

    假设我们希望文本位于三角形中心的一半:

    float textYHeight = triangleHeight/2; 
    

    由于相似三角形的边成比例,因此我们使用以下公式计算此时三角形的宽度: baseOfTriangleA/baseOfTriangleB = heightOfTriangleA/altitudeOfTriangleB;

    float triangleWidthAtTextYLocation = (textYHeight * triangleBase)/triangleAltitude;
    

    现在我们知道三角形在这个位置的宽度是多少,我们可以迭代不同的文本比例,直到文本宽度小于值 triangleWidthAtTextYlocation。

            float scale = getResources().getDisplayMetrics().density;
    
            int scaleFactor = 0;
            drawPaint.setTextSize((int) (scaleFactor * scale));
            Rect textBounds = new Rect();
            drawPaint.getTextBounds("50%", 0, "50%".length(), textBounds);
            while(textBounds.length < triangleWidthAtTextYLocation){
                 // Re-measure the text until it exceeds the width
                 scaleFactor++;
                 drawPaint.setTextSize((int) (scaleFactor * scale));
                 drawPaint.getTextBounds("50%", 0, "50%".length(), textBounds);
             }
    
             // Once we know the scaleFactor that puts it over the width of the triangle
             // at that location, we reduce it by 1 to be just under that width:
             scaleFactor = Maths.abs(scaleFactor - 1);
             // final text size:
             drawPaint.setTextSize((int) (scaleFactor * scale));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多