Android:在形状绘制的准确位置方面需要帮助

时间:2016-06-10 08:52:55

标签: android canvas

在我的Android项目中,我在绘图代码中遇到了一些困难,所以我在下面编写了一个MCVE来演示我遇到的问题。

通过运行此示例,并在屏幕上执行触摸,您可以看到两个圆圈即将出现。

您可以看到红色的位置在触摸点周围准确且一致地定位。

对于绿色的那个,你可以看到它的位置在某种程度上是随机的,重复触摸屏幕。

红色圆圈是使用ImageView创建的,其源为ball.xml。对于绿色的,它由Canvas.drawCircle()完成。

所以:

  

如何更正代码以制作红色圆圈和绿色圆圈   无论屏幕的分辨率和dpi如何,触摸时都会出现在完全相同的位置?

另外,顺便说一句,500X1000尺寸(Bitmap.createBitmap(500, 1000))只是随意设置,应该根据设备的屏幕尺寸。

MainActivity

package com.prime.testdraw;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    ImageView ivPhoto;
    FrameLayout fl;
    ImageView ivBall;
    private Canvas myCV;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivPhoto = ((ImageView) findViewById(R.id.ivPhoto));
        fl = ((FrameLayout) findViewById(R.id.fl));
        ivBall = ((ImageView) findViewById(R.id.ivBall));
        myCV = initDraw(ivPhoto);

        ivPhoto.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                myCV = initDraw(ivPhoto);
                ivBall.setX(motionEvent.getX() - ivBall.getWidth()/2);
                ivBall.setY(motionEvent.getY() - ivBall.getHeight()/2);
                Paint p = new Paint();
                p.setStrokeWidth(3);
                p.setColor(Color.GREEN);
                p.setTextSize(100);

                int radius = 40;
                p.setStyle(Paint.Style.STROKE);
                myCV.drawCircle(motionEvent.getX() - radius, motionEvent.getY() - radius, radius, p);
                ivPhoto.invalidate();

                return false;
            }
        });
    }
    private Canvas initDraw(ImageView imageView) {

        Bitmap bmp = Bitmap.createBitmap(500, 1000, Bitmap.Config.RGB_565);
        Canvas cv = new Canvas(bmp);

        imageView.setImageDrawable(new BitmapDrawable(getResources(), bmp));
        imageView.invalidate();
        return cv;
    }

}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fl">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/ivPhoto"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <ImageView
        android:layout_width="52dp"
        android:layout_height="52dp"
        android:id="@+id/ivBall"
        android:layout_gravity="left|top"
        android:src="@drawable/ball" />

</FrameLayout>

ball.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
    <stroke
        android:width="4dp"
        android:color="#FF0000" />

    <gradient android:startColor="#FFFF0000" android:endColor="#80FF0000"
        android:angle="270"/>
</shape>

1 个答案:

答案 0 :(得分:0)

Canvas.drawCircle使用以下参数:

  1. cx float:要绘制的圆圈中心的x坐标
  2. cy float:要绘制的圆圈中心的y坐标
  3. radius float:要绘制的圆的半径
  4. paint Paint:用于绘制圆圈的颜料
  5. 因此,不要在调用时减去半径,只需直接调用drawCircle:

    myCV.drawCircle(motionEvent.getX(), motionEvent.getY(), radius, p);
    

    来源:Android Canvas doc