适当地在画布上绘制文本

时间:2012-12-20 04:15:28

标签: android

我尝试在我的应用中绘制文本和位图图像。我希望将文本绘制在位图图标上方,但我很难实现这一点。

如何修改或更改我的代码,使其显示在每个图标Screen shot of the app notice the text is behind the icon

的顶部

我的代码:

protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);



    xCanvas = canvas.getWidth();
    yCanvas = canvas.getHeight();



    Paint textPaint2 = new Paint();
    textPaint2.setStyle(Paint.Style.FILL_AND_STROKE);
    textPaint2.setAntiAlias(true);
    textPaint2.setColor(Color.WHITE);
    textPaint2.setTextSize(30);
    textPaint2.setTextAlign(Align.CENTER);


    destination = new Location("manual");

    for (int j = 0; j < placesListItems.size(); j++){
        song = placesListItems.get(j);

        this.lat = myLat.get(j);
        this.lng = myLng.get(j);
        this.name=song.get(KEY_NAME);

        try {
            this.icon = ICON.get(j);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //  Log.d("the latitude",(String.valueOf(this.lat)));
        //  Log.d("the longitude",(String.valueOf(this.lng)));
        // Double.parseDouble(song.get(KEY_LNG));



        destination.setLatitude(this.lat);
        destination.setLongitude(this.lng);




        //Log.d("Place name",name );

        this.location.distanceTo(destination);

        // compute rotation matrix
        float rotation[] = new float[9];
        float identity[] = new float[9];
        if (lastAccelerometer != null && lastCompass != null) {
            boolean gotRotation = SensorManager.getRotationMatrix(rotation,
                    identity, lastAccelerometer, lastCompass);
            if (gotRotation) {
                float cameraRotation[] = new float[9];
                // remap such that the camera is pointing straight down the
                // Y
                // axis
                SensorManager.remapCoordinateSystem(rotation,
                        SensorManager.AXIS_X, SensorManager.AXIS_Z,
                        cameraRotation);

                // orientation vector
                orientation = new float[3];
                SensorManager.getOrientation(cameraRotation, orientation);

                canvas.save();

                // Translate, but normalize for the FOV of the camera --
                // basically, pixels per degree, times degrees == pixels
                float dx = (float) ((canvas.getWidth() / horizontalFOV) * (Math
                        .toDegrees(orientation[0]) - this.location
                        .bearingTo(destination)));
                float dy = (float) ((canvas.getHeight() / verticalFOV) * Math
                        .toDegrees(orientation[1]));


                // wait to translate the dx so the horizon doesn't get
                // pushed off
                canvas.translate(0.0f, 0.0f - dy);


                // now translate the dx
                canvas.translate(0.0f - dx, 0.0f);

                canvas.drawText((truncate(this.name,10).concat("...")), canvas.getWidth()/2 - 50, canvas.getHeight() / 2 - 100,
                        textPaint2);

                canvas.drawBitmap(icon, canvas.getWidth()/2 - icon.getWidth()/2, canvas.getHeight()/2 - icon.getHeight()/2, null);

                canvas.restore();
            }
        }

    }


}

1 个答案:

答案 0 :(得分:3)

诀窍是掌握您正在使用的字体的指标。您可以使用

执行此操作
Paint.FontMetrics fm = textPaint2.getFontMetrics();
int fontHeight = fm.bottom - fm.top;

(调整使用底部和顶部似乎更准确)

然后,您可以根据实际文字大小调整垂直位置(而不是使用任意数字)

假设您有一个要绘制的图标,其上方有两行文本(标签和坐标),并且您希望图标以x,y为中心。以下示例演示了这一点。

注意:在draw方法中分配Paint对象 - 这实际上是一个坏主意,因为对象总是相同的,最终会开始垃圾收集器。很多。分配一次并重复使用。我也证明了这一点。

我绘制交叉线以指向目标x,y值;你不需要它们,但它有助于准确显示目标相对于图标和文本的位置。

package com.javadude.sample;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }

    public static class MyView extends View {    
        public MyView(Context context) {
            super(context);
        }

        private Paint textPaint;
        private Paint linePaint;
        private Drawable drawable;
        private float textHeight;
        private float baselineOffset;

        private void drawIconAndText(Canvas canvas, int centerX, int centerY, Drawable drawable, String text) {

            // draw the drawable centered on (targetXcenter, targetYcenter)
            int w = drawable.getIntrinsicWidth();            
            int h = drawable.getIntrinsicHeight();

            // determine upper-left corner of drawable location
            int x = centerX - w/2;
            int y = centerY - h/2;

            // draw the icon
            drawable.setBounds(x, y, x+w, y+h);
            drawable.draw(canvas);

            float textY = y - baselineOffset;

            // note that drawText centers the text at the given location due to Align.CENTER
            canvas.drawText(text, centerX, textY, textPaint);

            // if you had used Align.LEFT, you would need to offset the start of the text as follows:
            //     float textWidth = textPaint.measureText(text);
            //     canvas.drawText(text, centerX - textWidth/2, textY, textPaint);

            // draw the coordinates above it
            textY = textY - textHeight; // move up a line
            canvas.drawText("(" + centerX + "," + centerY + ")", centerX, textY, textPaint);
        }

        private void initPaint() {
            linePaint = new Paint();
            linePaint.setStyle(Paint.Style.STROKE);
            linePaint.setColor(Color.BLUE);
            textPaint = new Paint();
            textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            textPaint.setAntiAlias(true);
            textPaint.setColor(Color.WHITE);
            textPaint.setTextSize(30);
            textPaint.setTextAlign(Align.CENTER);
            FontMetrics fontMetrics = textPaint.getFontMetrics();
            baselineOffset = fontMetrics.bottom; 
                // bottom is the maximum amount that the text descends
                // I'm not sure why this is different from descent...  
            textHeight = fontMetrics.bottom - fontMetrics.top;
            drawable = getResources().getDrawable(R.drawable.ic_launcher);
        }

        @Override protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            int width = canvas.getWidth();
            int height = canvas.getHeight();

            int targetXcenter = width/2;
            int targetYcenter = height/2;

            // only allocate objects once it at all possible!
            if (textPaint == null)
                initPaint();

            canvas.drawColor(Color.BLACK); // draw background

            // draw lines to show where the target is
            canvas.drawLine(0, targetYcenter, width-1, targetYcenter, linePaint);
            canvas.drawLine(targetXcenter, 0, targetXcenter, height-1, linePaint);

            drawIconAndText(canvas, targetXcenter, targetYcenter, drawable, "Sample Text");

            // draw lines to show where the target is
            canvas.drawLine(0, 200, width-1, 200, linePaint);
            canvas.drawLine(100, 0, 100, height-1, linePaint);

            drawIconAndText(canvas, 100, 200, drawable, "More Text");
        }
    }
}