1

アプリでテキストとビットマップの画像を描画しようとしています。テキストをビットマップアイコンの上に描画したいのですが、それを実現するのに問題があります。

各アイコンの上部に表示されるようにコードを変更または変更するにはどうすればよいですか?アプリのスクリーンショットは、テキストがアイコンの後ろにあることに注意してください

私のコード:

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

    }


}
4

1 に答える 1

3

秘訣は、使用しているフォントのメトリックを取得することです。これを使用して行うことができます

Paint.FontMetrics fm = textPaint2.getFontMetrics();
int fontHeight = fm.bottom - fm.top;

(より正確と思われる下と上を使用するように微調整)

その後、(任意の数値を使用するのではなく) 実際のテキスト サイズに基づいて垂直方向の位置を調整できます。

その上に 2 行のテキスト (ラベルと座標) を描画するアイコンがあり、アイコンの中心を 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");
        }
    }
}
于 2012-12-20T04:24:53.770 に答える