2012-12-06 75 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 
     }