如何为Android自定义View添加OnClick事件

8

我有两张图片在屏幕上移动,一张是球,另一张是人物。

我希望当用户触摸到人物图像时,球掉落。

我的问题是我似乎不能添加一个onclick/ontouch事件并使其正常工作。

我没有正确实现它,有人能帮忙吗?

我已经包含了下面的三个类。Greg是人物,球被命名为ball :)

TestAnimationActivity.java

 package com.test.firstAnimation;

    import android.app.Activity;
    import android.os.Bundle;

    public class TestAnimationActivity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new MyAnimationView(this));
       }
    }

Sprite.java

package com.test.firstAnimation;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class Sprite extends View implements OnClickListener{

     private static int gregCoordX = 410; // the x coordinate at the canvas for greg
     private Bitmap img; // the image of Greg
     private Bitmap img2; // the image of pointer 
     private static int gregCoordY = 125; // the y coordinate at the canvas for greg
     private static int pointCoordX = 10;
     private static int pointCoordY = 10;
     private static int count = 1;
     private static int ballSpeed = 25;
     private static boolean goingRight = false;
     private static boolean goingLeft = true;
     private static boolean pointerGoingRight = false;
     private static boolean pointerGoingLeft = true;


    public Sprite(Context context, int drawable) {

        super(context);

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        img = BitmapFactory.decodeResource(context.getResources(), drawable);
        img2 = (BitmapFactory.decodeResource(context.getResources(), drawable));
        count++;
    }

    public static int getCount() {
        return count;
    }

    void setX(int newValue) {
        gregCoordX = newValue;
    }

    public static int getX() {
        return gregCoordX;
    }

    public static int getY() {
        return gregCoordY;
    }

    public static int getBX() {
        return pointCoordX;
    }

    public static int getBY() {
        return pointCoordY;
    }

    public Bitmap getBitmap() {
        return img;
    }

    public Bitmap getImg2() {
        return img2;
    }

    public static void dropBall()
    {
        pointCoordY++;
    }

    public static void moveBall(int x) {

           // check the borders
            //if more than ten go right
            //if ten go left
            //if more than 250 go left
            if (x <= 10 && pointerGoingLeft)
            {
            pointCoordX = pointCoordX + ballSpeed;
            pointerGoingRight = true;
            pointerGoingLeft = false;
            }
            else if (x >= 410 && pointerGoingRight)
            {
                pointCoordX = pointCoordX - ballSpeed;
                pointerGoingLeft = true;
                pointerGoingRight = false;
            }
            else if (pointerGoingRight)
                pointCoordX = pointCoordX + ballSpeed;
            else
                pointCoordX = pointCoordX - ballSpeed;

            if(MyAnimationView.ballDropping == true)
            {
                while (pointCoordY<gregCoordY)
                    dropBall();
            }
    }

    public static void moveGreg(int x) {

        if (x <= 10 && goingLeft)
        {
        gregCoordX = gregCoordX + count;
        goingRight = true;
        goingLeft = false;
        }
        else if (x >= 410 && goingRight)
        {
        gregCoordX = gregCoordX - count;
        goingLeft = true;
        goingRight = false;
        }
        else if (goingRight)
        gregCoordX = gregCoordX + count;
        else
        gregCoordX = gregCoordX - count;
}

    @Override
    public void onClick(View arg0) {
        dropBall();
    }
}

MyAnimationView.java

package com.test.firstAnimation;

import android.content.Context;
import android.graphics.Canvas;
import android.view.View;

public class MyAnimationView extends View{

    private Sprite greg;
    private Sprite ball;
    private int xCoOr;
    private int ballXCoOr;
    public static boolean ballDropping;

    public MyAnimationView(Context context) {
        super(context);

        ballDropping = false;
        greg = new Sprite(context,R.drawable.greg);
        ball = new Sprite(context, R.drawable.ball);

        OnClickListener gregClicked = new OnClickListener() {
            public void onClick(View v) {
            ballDropping = true;
            }
        };
        greg.setOnClickListener(gregClicked);
        }

    @Override protected void onDraw(Canvas canvas) {

     canvas.drawColor(0xFFFFFFFF);                                   //white background      

     ballXCoOr = Sprite.getBX();  
     xCoOr = Sprite.getX();
     Sprite.moveGreg(xCoOr);                                         //move ball left or right depending
     Sprite.moveBall(ballXCoOr);

     if(ballDropping == true)
     {
         Sprite.dropBall();
     }

     canvas.drawBitmap(greg.getBitmap(), xCoOr, Sprite.getY(), null);
     canvas.drawBitmap(ball.getBitmap(), ballXCoOr, Sprite.getBY(), null);
     invalidate();
     }
}

感谢您的提前帮助,我已经卡了好几天了! Ben

抱歉格式不佳,这是我的第一篇帖子 :) - Ben Taliadoros
我认为你的代码不起作用,因为Sprite视图不是MyAnimationView的子视图。onClick监听器不会触发,因为这些视图从未被使用 - 你只是读取它们的位图并在onDraw中绘制它们。我会把这个作为答案发布,但这是问题,而不是解决方案。 - David Snabel-Caunt
看看这个解决方案:https://dev59.com/YGMl5IYBdhLWcg3w96-L#17978891 - Bobs
2个回答

8
    float touched_x, touched_y;
    boolean touched = false;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        touchCounter++;
        touched_x = event.getX();
        touched_y = event.getY();

        int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            touched = true;
            break;
        case MotionEvent.ACTION_MOVE:
            touched = true;
            break;
        case MotionEvent.ACTION_UP:
            touched = false;
            break;
        case MotionEvent.ACTION_CANCEL:
            touched = false;
            break;
        case MotionEvent.ACTION_OUTSIDE:
            touched = false;
            break;
        default:
        }
        return true; // processed
    }

然后;
    if (touched) {
        //control here
    }

touched_x, touched_y 是屏幕上被点击的点的坐标。您可以将 Greg 的坐标和这些坐标进行比较。如果相同,则执行您想要做的操作。


6


public class CustomView extends View implements OnClickListener {

    public CustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomView(Context context) {
        super(context);
        init();
    }

    private void init(){
        setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        // Do whatever you need to
    }

}

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