2012-12-06 76 views
3

我必须在地图视图上放置标记并在标记上写入数字。我已经这样做了,但文本对齐方式因不同的分辨率而异。波纹管是参考代码绘制图像的文本中间android

 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位置在此分辨率上看起来不同。任何人都可以请建议我究竟发生了什么错误?在不同大小的设备上做同样的事情有没有什么基础?提前致谢。

回答

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()); 
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); 

选择您所选择的构造..好运里面的颜色!

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); 
+0

或者,如果垂直对齐是不是真的很重要,你可以直接调用'paint.setTextAlign(Paint.Align.CENTER)'[Paint.html#setTextAlign(HTTP ://developer.android.com/reference/android/graphics/Paint.html#setTextAlign(android.graphics.Paint.Align)) – jlhuertas

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导致错误。

+0

我一直在寻找这个解决方案,仍然不知道为什么你必须转向它关闭,但似乎这样工作。 – Florian

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); 
+0

什么是群集? – jiduvah

+0

集群是我的课,它只是给一个值,如说10或11作为大小 – user1530779

0

我有同样的问题。我想在位图中绘制文本 - 在Google地图上进行聚类。实际上,它在位图的CENTER上绘制文本。写在科特林

代码

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 
     }