简体   繁体   中英

When someone touches a red circle on my app nothing happens

I am making an app that displays circles randomly on the screen. The circles are either red or green. The purpose of the app is so that when someone touches a green circle something good happens, like they get points added to their score. When a red circle is clicked something bad happens like a new activity is started and the page says you failed or something. Here is my code for this app. In this code i receive no errors, nothing in logcat, everything works just fine. The circles display randomly on the screen as well as the score which is by default 0. The problem i am having with this app is that when a red or a green circle is clicked nothing happens.

public DrawingView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub

    }
    RectF rectf = new RectF(0, 0, 200, 0);

    private static final int w = 100;
    public static int lastColor = Color.BLACK;
    private final Random random = new Random();
    private final Paint paint = new Paint();
    private final int radius = 230;
    private final Handler handler = new Handler();
    public static int redColor = Color.RED;
    public static int greenColor = Color.GREEN;
    int randomWidth = 0;
    int randomHeight = 0;
    public static int addPoints = 0;


    private final Runnable updateCircle = new Runnable() {
        @Override 
        public void run() {
            lastColor = random.nextInt(2) == 1 ? redColor : greenColor;
            paint.setColor(lastColor);
            invalidate();
            handler.postDelayed(this, 1000);

        }
    };

    @Override 
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        handler.post(updateCircle);
    }

    @Override 
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        handler.removeCallbacks(updateCircle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // your other stuff here
        if(random == null){
            randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
            randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
        }else {
            randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
            randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
        }

        canvas.drawCircle(randomWidth, randomHeight, radius, paint);

        paint.setColor(Color.BLACK);
        paint.setTextSize(150);
        canvas.drawText("Score: " + addPoints, 120, 300, paint);
    }

    public boolean onTouch(View v, MotionEvent event) {
   int x = (int) event.getX();
   int y = (int) event.getY();
   if(isInsideCircle(x, y) ==  true){
      //Do your things here
       if(redColor == lastColor){
          Intent i = new Intent(v.getContext(), YouFailed.class);
          v.getContext().startActivity(i);
       } else {
           addPoints++;
       }
   }else {

   }
   return true;
}

public boolean isInsideCircle(int x, int y){
  if ((((x - randomWidth)*(x - randomWidth)) + ((y - randomHeight)*(y - randomHeight))) < ((radius)*(radius))){
    return true;
  }
  return false; 
}


}
  1. Your view might not be implementing the View.OnTouchListener interface, hence it not calling the onTouch() method.

  2. Your view is not being set a View.OnTouchListener via the view's View.setOnTouchListener(View.OnTouchListener) method.

Android Developer Reference - View.OnTouchListener

Either way it feels wrong to make a view implement this interface to listen to itself. Instead you may want to take a look at the View.onTouchEvent(MotionEvent event) method; perhaps it serves your purpose (or it should in this case). Listener interfaces are supposed to be implemented by external components. Say, for example, if you wanted to make your TextView listen every time a Button or ImageView is touched, you could extend TextView/Button and make them implement the Listener interface then pass it to you view as a parameter of its setOnTouchListener(View.OnTouchListener) .

However, all views have a method called onTouchEvent() . This View.onTouchEvent() method should be used if you want to listen to events within the view itself, as it is by default called whenever the view is, well touched . Should you need a reference to the view itself with this approach, you call this since the view itself would be your current scope.

Android Developer Reference - View.onTouchEvent(MotionEvent event)

If you do it like this, all you would need to do in order to make your code work is change your onTouch() method to an override of onTouchEvent() like this: (Also added verification of touch action as suggested by Pooja and Tom so you don't take into account MOVE or UP events. Change DOWN for UP depending on when you want to trigger the event)

@Override
public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        if(isInsideCircle(x, y) ==  true) {
            //Do your things here
            if(redColor == lastColor){
                Intent i = new Intent(v.getContext(), YouFailed.class);
                this.getContext().startActivity(i);
            } else {
                addPoints++;
            }
        } else {
             //Handle case not inside the circle
        }
    }

    return true;
}

The onTouch method is meant to be used with OnTouchListener and would normally be defined outside your custom view class. For example:

    this.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // touch handling code
            return true;
        }
    });

In the case where you are looking for touch events inside your custom view, you should implement the onTouchEvent method. You may also want to check for either ACTION_UP or ACTION_DOWN or you will be processing multiple touch events.

@Override
public boolean onTouchEvent(MotionEvent event) {

    boolean result = false;

    if (event.getAction() == MotionEvent.ACTION_DOWN) {

        int x = (int) event.getX();
        int y = (int) event.getY();

        if(isInsideCircle(x, y) ==  true) {
            //Do your things here
            if(redColor == lastColor){
               Intent i = new Intent(v.getContext(), YouFailed.class);
               v.getContext().startActivity(i);
            } else {
               addPoints++;
            }
            result = true;
        }
    }

    return result;
}

See the following for more details: Input Events

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM