3

我必须在地图视图上放置标记并在标记上写一个数字。我已经这样做了,但是文本对齐方式在不同的分辨率下会有所不同。下面是参考代码

        float xVal = (float) curScreenCoords.x;  // Point curScreenCoords
        float yVal = (float) curScreenCoords.y-20; // Point curScreenCoords
        Bitmap bitmap = BitmapFactory.decodeResource ( context.getResources() , ( R.drawable.pin_number ) ) ;
        canvas.drawBitmap(bitmap, xVal, yVal, getInnerPaint()); 

        public Paint getInnerPaint() {
         if (innerPaint == null) {
             innerPaint = new Paint();
         }
        innerPaint.setARGB(255, 117, 161, 220); // blue
        innerPaint.setAntiAlias(true);  
        innerPaint.setStyle(Style.FILL);
        return innerPaint;
        }
        canvas.drawText(String.valueOf(10), xVal+20, yVal+22, getCountPaint()); // 10 is just for example, it can vary to one digit to two to three 
        public Paint getCountPaint() {
        if (innerPaint == null) {
        innerPaint = new Paint();
        }
        innerPaint.setARGB(255, 255, 255, 255); 
        innerPaint.setAntiAlias(true);  
        innerPaint.setStyle(Style.FILL);
        innerPaint.setTextSize(12f);
        innerPaint.setTextAlign(Align.CENTER);
        return innerPaint;
       }

一切正常,除了文本对齐,此代码适用于 480*800 分辨率。文本在画布中完全居中对齐。x, y 位置在图像上是完美的,但在 320*480 上看起来并不完美。在此分辨率下,文本的 x 和 y 位置看起来不同。谁能建议我到底发生了什么错误?在不同尺寸的设备上做同样的事情有什么基本原理吗?提前致谢。

4

6 回答 6

5

我认为你可以测量文本曾经写在画布上的宽度和高度,然后用它来居中。就像是:

String text = "whatever";
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, (canvas.getWidth() - bounds.width()) / 2, (canvas.getHeight() - bounds.height()) / 2, paint);
于 2012-12-06T13:10:14.573 回答
5

嗨,我想上面给出的答案都不够好,所以我发布我的答案试试吧,伙计们可以在所有设备上工作,而且一点也不复杂

Canvas canvas = new Canvas(bitmap);

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//paint.setTextAlign(Align.CENTER);
paint.setColor(activity.getResources().getColor(R.color.white));
paint.setTextSize(30);

// draw text to the Canvas center
Rect boundsText = new Rect();
paint.getTextBounds(String.valueOf(cluster.getMarkerList().size()), 0, 
    String.valueOf(cluster.getMarkerList().size()).length(), boundsText);
int x = (bitmap.getWidth() - boundsText.width()) / 2;
int y = (bitmap.getHeight() + boundsText.height()) / 2;

canvas.drawText(String.valueOf(cluster.getMarkerList().size()), x, y, paint);
于 2013-11-06T06:48:48.297 回答
2

您的值curScreenCoords.y-20xVal+20, yVal+22所有分辨率的恒定像素偏移,但它们应该取决于设备的像素密度,如下所示:

xOffset = (int) (13.33f * context.getResources().getDisplayMetrics().density + 0.5f);
yOffset = (int) (14.67f * context.getResources().getDisplayMetrics().density + 0.5f);
canvas.drawText(String.valueOf(10), xVal + xOffset, yVal + yOffset, getCountPaint());
于 2012-12-06T12:51:44.997 回答
1

确保检查硬件加速是否已关闭。在 4.1.2 和其他设备(三星 Galaxy Tag 2.0)上,您会收到致命信号 11 错误。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

这纠正了我在使用此代码时遇到的问题。canvas.drawText 导致错误。

于 2013-09-03T16:47:53.223 回答
0

您可以扩展 Image 类并覆盖它的 onDraw。如下

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.widget.ImageView;

/**
 * @author amit
 * 
 */
public class CustomImageView extends ImageView {
    private int notificationCount;
    private Paint paint;

    /**
     * @param context
     */
    public CustomImageView(Context context) {
        super(context);
        notificationCount = 0;
        paint = new Paint();
        paint.setColor(Color.RED);
        ColorFilter cf = new ColorFilter();
        paint.setColorFilter(cf);
        paint.setStyle(Paint.Style.FILL);
        paint.setFakeBoldText(true);
        paint.setTextSize(15);
    }

    public synchronized void incrementNotification() {
        notificationCount--;
        this.invalidate();
    }

    public synchronized void decrementNotification() {
        notificationCount++;
        this.invalidate();
    }

    /**
     * @return the notificationCount
     */
    public synchronized int getNotificationCount() {
        return notificationCount;
    }

    /**
     * @param notificationCount
     *            the notificationCount to set
     */
    public synchronized void setNotificationCount(int notificationCount) {
        this.notificationCount = notificationCount;
        this.invalidate();
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.widget.ImageView#onDraw(android.graphics.Canvas)
     */
    @Override
    protected void onDraw(Canvas canvas) {
        // System.out.println("OnDraw is called");
        super.onDraw(canvas);
        if (notificationCount == 0) {
            return;
        }
        canvas.drawText(String.valueOf(notificationCount), 0, 0, paint);
    }

}

比您可以调用以下任何方法

incrementNotification(); 
decrementNotification();
setNotification(int number);

在构造函数中选择您选择的颜色.. 祝你好运!!

于 2012-12-06T12:48:51.487 回答
0

我遇到过同样的问题。我想在位图中绘制文本 - 用于在谷歌地图上进行聚类。实际上它在位图的中心绘制文本。

用 Kotlin 编写的代码

fun createCircleBitmapWithTextInside(context: Context, @DrawableRes drawableId: Int, text: String = "POI"): Bitmap{
            val scale = context.resources.displayMetrics.density

            var bitmap = getBitmap(context, drawableId)//BitmapFactory.decodeResource(res, drawableId)
            var bitmapConfig = bitmap.config ?: Bitmap.Config.ARGB_8888
            // resource bitmaps are imutable,
            // so we need to convert it to mutable one
            bitmap = bitmap.copy(bitmapConfig, true)

            val canvas = Canvas(bitmap)
            val paint = Paint(ANTI_ALIAS_FLAG)
            paint.color = ResourceUtils.getColor(context, R.color.white)
            paint.textSize = (18 * scale)
            paint.setShadowLayer(1f, 0f, 1f, Color.WHITE)
            paint.style = Paint.Style.FILL
            paint.textAlign = Paint.Align.CENTER

            val bound = Rect()
            paint.getTextBounds(text, 0, text.length, bound)
            val x = (canvas.width.toFloat() /2)
            // x - point to the center of width
            val y = canvas.height / 2 - (paint.descent() + paint.ascent()) / 2

/*            Timber.d("bitmap.width:${canvas.width} \tbound.width:${bound.width()} \tx:$x")
            Timber.d("bitmap.height:${canvas.height} \tbound.height:${bound.height()} \ty:$y")*/

            canvas.drawText(text, x, y, paint)
            return bitmap
        }
于 2017-07-12T11:07:36.600 回答