Android触摸事件未发生?

3

我一直在研究和努力修改我的代码,使得当用户触碰到“ghost”时,textview可以更新分数。

这是我第一个安卓应用程序,就目前而言(我在ontouch中添加了Log.w(),但是日志没有被发布,分数也没有增加或显示),onTouch(View v, MotionEvent event)似乎从未被调用。以下是我的代码。

package com.cs461.Ian;

//TODO:Add accelerometer support
//TODO:Add Clickable ghosts
//TODO:Add camera background
/*Completed:(As of 2:30am 4/16)
 * Activity launches
 * Ghost appears on screen
 * Ghost will randomly move around the screen
 */

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.TextView;

public class CameraActivity extends Activity{

Bitmap g;
Ghost a;
Ghost still;
SurfaceHolder mSurfaceHolder;
boolean firsttime=true;
int draw_x,draw_y,xSpeed,ySpeed,score=0;
TextView t;




@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.game);
    a = new Ghost(getApplicationContext());
    still = new Ghost(getApplicationContext());
    //requestWindowFeature(Window.FEATURE_NO_TITLE);
    a.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 20, 20);
    still.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 120, 120);
    t = (TextView) findViewById(R.id.t);
    t.setText("TEST SCORE TO SEE IF TEXTVIEW SHOWS UP");

    a.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                score++;
                t.setText("Score: "+score);

            }
            return true;
        }
    });
    still.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                score++;
                t.setText("Score: "+score);
                Log.w("CLICKED","Clicked on ghost "+score+" times");

            }
            return true;
        }
    });



    setContentView(new Panel(this));
}


class Panel extends View {
    public Panel(Context context) {
        super(context);
    }

    @Override
    public void onDraw(Canvas canvas) {
        //g.Initalise(BitmapFactory.decodeFile("/res/drawable-hdpi/ghost.png"), 200, 150, 5, 5);;
        update(canvas);
        invalidate();
    }

    /*Places ghost on screen and bounces it around in the screen. My phone is apparently only API level 4(the most up to date is 15) so i didn't code it
     *for the accelerometer yet.
     */
    public void update(Canvas canvas) {
        Random rand = new Random();
        if(firsttime){
            draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
            draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
            xSpeed = rand.nextInt(10);
            ySpeed = rand.nextInt(10);

            firsttime=false;
        }
         draw_x+=xSpeed;
         draw_y+=ySpeed;
        draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
        draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
         if (draw_x>this.getWidth()){
          draw_x = (this.getWidth()*2)-draw_x;
          xSpeed = rand.nextInt(10);
          if(xSpeed >=5)
              xSpeed=-xSpeed;
         }
         if (draw_y>this.getHeight()){
          draw_y = (this.getHeight()*2)-draw_y;
          ySpeed = rand.nextInt(10);
          if(ySpeed >=5)
              ySpeed=-ySpeed;
         }
         g = BitmapFactory.decodeResource(getResources(), R.drawable.ghost);
         canvas.drawBitmap(g, draw_x, draw_y, null);
         still.draw(canvas);
         a.update(canvas);


        }
    }


}

忘记添加 Ghost 类:

package com.cs461.Ian;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class Ghost extends View implements View.OnTouchListener{
public Ghost(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

private Bitmap mAnimation;
private int mXPos;
private int mYPos;
private Rect mSRectangle;
private int mSpriteHeight;
private int mSpriteWidth;
View v;
Rect dest;
int score = 0;

/*public Ghost() {
    mSRectangle = new Rect(0,0,0,0);
    mXPos = 80;
    mYPos = 200;
}*/



public void Initalize(Bitmap theBitmap, int Height, int Width) {
    mSRectangle = new Rect(0,0,0,0);
    mXPos = 80;
    mYPos = 200;
    mAnimation = theBitmap;
    mSpriteHeight = Height;
    mSpriteWidth = Width;
    mSRectangle.top = 0;
    mSRectangle.bottom = mSpriteHeight;
    mSRectangle.left = 0;
    mSRectangle.right = mSpriteWidth;
    dest = new Rect(mXPos, mYPos, mXPos + mSpriteWidth,
            mYPos + mSpriteHeight);

}
public void draw(Canvas canvas) {


    canvas.drawBitmap(mAnimation, mXPos, mYPos, null);
}

public void update(Canvas canvas) {
    new Random();

    mXPos = Math.round(System.currentTimeMillis() % (canvas.getWidth()*2)) ;
    mYPos = Math.round(System.currentTimeMillis() % (canvas.getHeight()*2)) ;
    if (mXPos>canvas.getWidth())
      mXPos = (canvas.getWidth()*2)-mXPos;
    if (mYPos>canvas.getHeight())
      mYPos = (canvas.getHeight()*2)-mYPos;

     draw(canvas);


}

public Rect getRect() {
    return mSRectangle;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
    score++;
    //CameraActivity.t.setText("Score: "+CameraActivity.score);
    Log.w("CLICKED","Clicked on ghost "+score+" times");
    return true; //doesn't work if returns false either
}


}

2
如果click函数始终相同,为什么不将其放入构造函数中幽灵的类定义中呢? - JustinDanielson
如果您将Log.w移动到操作if块之外会发生什么? - R.daneel.olivaw
在 Ghost 构造函数中添加 this.setClickable(true); - JustinDanielson
2
@JustinDanielson,这是不必要的,因为setOnTouchListener()调用将确保它被设置为可点击。+1 移动到类定义,除非当然现在正在测试以后变得更加复杂。 - Jared
@SnakeMan2058 收到了。我正在以类似的方式工作,因为我学习了一些对我来说非常新的组件,所以我肯定能理解这种思维方式。 - Jared
显示剩余2条评论
1个回答

3

在您的Activity中覆盖dispatchTouchEvent(MotionEvent event)以处理可能发生的所有触摸事件。如果下一个视图/布局可以处理事件,请返回falseMotionEvent传递给它们。


我覆盖它以每次返回false,但它仍然没有任何反应。我有点以为它会认为每个触摸都在幽灵上,但我想我是错了。我现在得去上其中一堂课,但几个小时后我会回来。 - SnakeMan2058
你能解释一下游戏背后的理念吗?同时我看到Ghost继承了Button,你可以扩展View并仍然使Ghost可点击/触摸。我覆盖dispatchTouchEvent的想法是所有的交互都将通过它来完成,你不需要传递任何事件,但这完全取决于你想要实现什么。 - techi.services
目前我想要的只是当触摸到幽灵时,我的textView递增。 - SnakeMan2058
好的,对于这样的情况,我会通过扩展View并实现View.OnTouchListener来创建Ghost。当它检测到被触摸时,在您的Activity中通过执行类似于((MyActivity)context).textView.getText()...的操作来增加TextView文本。(您可能需要将其转换为Int,然后再转换回String)在Ghost中完成。 - techi.services
抱歉,它仍然没有起作用 :/ 我按照您的建议实现了onTouch等功能,但我只是让它记录到LogCat中以查看是否有效,但它仍然没有起作用。对于所有问题,我感到很抱歉,但在经过近几周的尝试后,我真的不知道自己做错了什么。我更新了主贴中的代码以显示我所做的更改。 - SnakeMan2058
经过进一步查看代码,我会更改Panel以扩展ViewGroup并覆盖onInterceptTouchEvent。从Ghost中删除View.OnTouchListener。使用Panel来保持/访问Ghost的命中矩形,具体取决于您是永久还是仅在屏幕被触摸时需要它(每次触摸都可以做一个Ghost,但如果您有很多,处理所有这些可能需要时间,这将使UI线程延迟)。您可能需要从Panel运行后台线程来跟踪每个Ghost位置。 - techi.services

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