Android:在按钮点击时在自定义画布中绘制圆形

4
我正在制作一个简单的鼓组应用程序,用户可以点击按钮发出相应的声音,并在画布上的随机位置绘制一个圆圈。对于画布,我创建了一个名为CanvasView的自定义视图,然后将该CanvasView实现到MainActivity中,以便我每次通过MainActivity中的OnClickListener点击按钮时都能控制该视图。
然而,我不知道如何使用OnClickListener实际控制(在CanvasView上绘制圆圈)。我需要在这部分得到帮助。
这是我MainActivity类的代码:
public class MainActivity extends Activity {
//setup variables for soundpool
.
.
.
//implements CanvasView

CanvasView mCanvasView;

//set up soundID for each sound
.
.  
.
//setup buttons
Button mKick;
.
. 
.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
//set up soundpools 
.
. 
.

//example, the kick drum button
//kick drum
    mKick = (Button) findViewById(R.id.kick);
    mKick.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        soundPool.play(kick, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);

//          mCanvasView.draw(CanvasView.mCanvas);

    }
});

这是我为CanvasView编写的代码。
public class CanvasView extends View {
public Paint mPaint;
public static Canvas mCanvas;
//constructor
public CanvasView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mPaint = new Paint();
}
//what I want to draw is here
protected void onDraw(Canvas canvas) {
    mCanvas = canvas;
    super.onDraw(mCanvas);
    canvas.drawColor(Color.GRAY);
    mPaint.setColor(Color.BLUE);
    mPaint.setStyle(Style.STROKE);
    mPaint.setAntiAlias(true);
    canvas.drawCircle(30, 30, radius, mPaint);

这是我的MainActivity的布局XML:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/GridLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:columnCount="3"
android:orientation="horizontal"
android:rowCount="5"
tools:context=".GridXMLActivity" >

<Button
    android:id="@+id/kick"
    android:layout_width="78dp"
    android:layout_height="wrap_content"
    android:layout_column="1"
    android:layout_gravity="center_horizontal|fill_vertical"
    android:layout_row="3"
    android:text="Kick" />

<com.example.virtualdrumset.CanvasView
    android:id="@+id/canvasView1"
    android:layout_width="143dp"
    android:layout_height="169dp"
    android:layout_column="1"
    android:layout_gravity="left|top"
    android:layout_row="0" />

非常抱歉给您带来任何不便或错误,这是我第一次提问。

在IT技术方面,您需要注意的是保持良好的代码规范和清晰的注释。此外,及时更新软件和应用程序可以确保您的设备始终保持最新版本并且安全受到保护。


我没有完全理解你的问题。你说的“我不知道如何使用OnClickListener实际控制(在CanvasView上绘制圆形)。”是什么意思?你想每次点击按钮时都绘制一个圆形吗?比如第二次点击按钮时绘制第二个圆形,第三次点击按钮时绘制第三个圆形吗? - Abhishek V
是的,我的要求是每次单击按钮时绘制一个圆,但每次后都要刷新。 - user3648721
1个回答

3

不应该直接从活动中调用canvasonDraw函数。相反,应在画布视图中创建一个公共方法,并在那里编写逻辑并在结尾处调用invalidate方法。这将调用onDraw方法,并根据您的新逻辑重新绘制屏幕上的内容。

如果您希望每次单击按钮时在屏幕上随机绘制一个圆,则可以执行以下操作:

public class CanvasView extends View {
    public Paint mPaint;
    public static Canvas mCanvas;
    private int mPivotX = 0;
    private int mPivotY = 0;
    private int radius = 60;

    //constructor
    public CanvasView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
    }

    public void drawCircle() {

        int minX = radius * 2;
        int maxX = getWidth() - (radius *2 );

        int minY = radius * 2;
        int maxY = getHeight() - (radius *2 );

        //Generate random numbers for x and y locations of the circle on screen
        Random random = new Random();
        mPivotX = random.nextInt(maxX - minX + 1) + minX;
        mPivotY = random.nextInt(maxY - minY + 1) + minY;

        //important. Refreshes the view by calling onDraw function
        invalidate();

    }

    //what I want to draw is here
    protected void onDraw(Canvas canvas) {
        mCanvas = canvas;
        super.onDraw(mCanvas);
        canvas.drawColor(Color.GRAY);
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Style.STROKE);
        mPaint.setAntiAlias(true);
        canvas.drawCircle(mPivotX, mPivotY, radius, mPaint);
    }
}

然后在按钮点击事件中

mKick.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        soundPool.play(kick, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);

          mCanvasView.drawCircle()

    }

希望这能帮到你!

谢谢,但是当我点击时应用程序崩溃了,错误日志指向按钮的onclicklistener。 - user3648721
什么是异常?你能发布异常的完整LogTrace吗? - Abhishek V
致命的异常:主要 java.lang.NullPointerException 位于com.example.virtualdrumset.MainActivity$3.onClick(MainActivity.java:111) 位于android.view.View.performClick(View.java:4147) 在android.view.View$PerformClick.run(View.java:17161) 处理程序为android.os.Handler.handleCallback(Handler.java:615) 派发消息为android.os.Handler.dispatchMessage(Handler.java:92) 在android.os.Looper.loop(Looper.java:213)处循环 在android.app.ActivityThread.main(ActivityThread.java:4787)执行 在java.lang.reflect.Method.invokeNative(Native Method)中进行本地方法调用 在java.lang.reflect.Method.invoke(Method.java:511)中进行调用 - user3648721
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)处运行 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)处 在dalvik.system.NativeStart.main(Native Method)处 - user3648721
1
编辑:我忘记初始化CanvasView了,现在它可以工作了。非常感谢你。 - user3648721
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接