我想查看事件是否已初始化但出现错误

I want to see if event is initialized or not but get an error

我有 2 个 class,第一个是 Sprite,第二个是 GameView。我在 GameView class 中有一个 onTouchEvent,我想在触摸事件时更改精灵方向和动画。但是,我尝试以任何方式解决 sprite class 中的事件我得到一个 Variable might not have been initialized 因此我想检查事件是否已初始化 - 虽然这给了我同样的错误!

雪碧class:

    MotionEvent event;  // These three declarations is just to get them in
    int xcoords;        // the scope - not sure it's the right way.
    int ycoords;

    if (gameView.onTouchEvent(event, xcoords, ycoords) != null) {  // This
    // gives me the error, specifically on event, xcoords and ycoords.

        MotionEvent event = this.gameView.onTouchEvent(event.getPointerCount());
        int isPushedDown = event.getPointerCount();

        if (isPushedDown == 0) {

            srcX = 1;
            srcY = 3;

            Rect srcNoMove = new Rect(srcX, srcY, srcX, srcY);

            canvas.drawBitmap(bmp, srcNoMove, dst, null);

        }

    }

GameView 事件:

public boolean onTouchEvent(MotionEvent event, float xcoord, float ycoord) {
        if (System.currentTimeMillis() - lastClick > 500) {
            lastClick = System.currentTimeMillis();
    }

    xcoord = event.getX();
    ycoord = event.getY();

    return onTouchEvent(event, xcoord, ycoord);

}

如何解决这个问题? 用 null 和 2 次 = 0; 声明上面的变量给出了一个布尔值不能为 null 的问题,并且做 if (!gameView.onTouchEvent(event)) { 不只是 return 我上面说的 null 吗?

我想检查变量是否已启动,如果是,请执行一些操作。

这里的问题是未初始化的变量和已初始化但值为[=的变量之间存在差异10=]。如果变量未初始化(如 event, xcoordsycoords 在你的问题中),你不能将它用于 任何东西 ,包括检查它的 null 值。在以任何方式使用变量之前,必须确保变量已初始化为某个值。

如果您想摆脱 Variable might not be initialized,您可以声明一个初始值为 null 的对象,然后再测试是否为 null(如 if(object != null))。

基元则不同,因为它们不能为空。但是,Java 中内置了 类,它们使用这些原语作为基础。

您可以将 int xcoords 更改为 Integer xcoords = null。然后它将具有空值,您可以使用我上面描述的语法适当地测试空值。

Java 每个基元都有 类 这样的。 intIntegerbooleanBoolean,等等,大部分应该很容易搞清楚。

首先。

MotionEvent event = this.gameView.onTouchEvent(event.getPointerCount());

不好的做法。


中学

if (gameView.onTouchEvent(event, xcoords, ycoords) != null) {

不好的做法。 onTouchEvent 必须 return 布尔结果。不是一个对象。


但是

您需要在使用前初始化一个变量。 "VERY SMART" Java 编译器给你报错,因为很可能你在运行时有 NullPointerException

MotionEvent event;

if(event.getX() != 0f) // compile error.

修复:

MotionEvent event = null; // In good case - you need use obtain(...) method of MotionEvent class.

if(event!=null && event.getX() != 0f) // All ok.

First there is not enough code posted to tell exactly what is happening, and the rest of code is rather bad and I just cannot even imagine what you are trying to do here and what was your actual problem. Maybe your first draft code before you tried to fix it in wrong way would be more telling.

gameView.onTouchEvent(event, xcoords, ycoords) != null 

In above code you are not actually comparing whether your onTouchEvent is assigned in above code, you are calling it, and since its return value is boolean you cannot compare it with null

If gameView is instance of GameView class, then you don't have to check whether your event is initialized (actually, it is not event but method of your GameView class) and you can use it if gameView variable is initialized. So quite possible is that you actually want to test gameView != null

Also your GameView onTouchEvent method is calling itself recursively with return onTouchEvent(event, xcoord, ycoord);


While you do have issues with your code, real problem here seems to be that you want to go forward way to fast, and you are trying to skip learning the basics. Another issue is that when you bump into an issue, you are listening to compiler trying to purely satisfy its errors without considering what you are actually doing. Compilers are stupid, don't let them lead the way. You are the boss here.

So when compiler tells you that you don't have variable event in scope, you have to stop and think what is the actual meaning. Do you really need event variable there or not? If you just forgot declaring it, then go ahead and do it, but if this kind of error (or any other error) has caught you by surprise then you have to stop and rethink your steps.

Now back to some basics.

public class GameView
{
   // onTouchEvent is method of GameView class
   // it can only be called on valid (non-null) instance of GameView class
   // when you have valid instance of GameView class all its methods 
   // can be used, you don't have to check whether they are null 
   //
   // return value of onTouchEvent is declared as boolean and that 
   // is the only value it can possibly return
   // passed parameters are event, xcoord and ycoord and they can be used inside 
   // onTouchEvent the way you see fit. 
   // since event is object (depending on class design) you can change its state and 
   // those changes will be preserved after onTouchEvent finishes. 
   // xcoord and ycoord are primitive types passed as value and whatever 
   // you do to them those changes will not survive after onTouchEvent.

   public boolean onTouchEvent(MotionEvent event, float xcoord, float ycoord) 
   {         
      xcoord = event.getX(); // this value will be lost the moment onTouchEvent returns
      return true; // or return false 
   }

}

First question in your classes design is what exactly should happen when user touches the screen. Does your Sprite has to react on touch events that only happen when actual Sprite location is touched, or it has to react no matter where touch occurred. In first case the best course of action would be to implement touch detection directly inside Sprite class. In second case, you have to implement touch detection inside GameView class and then direct your sprite instance to do something.

I am assuming that both Sprite and GameView are extending View class so we can tap in into default touch event dispatching overriding onTouchEvent method.

First way - process touch inside Sprite. In this case GameView does not need to know anything about Sprite and does not need Sprite instance

public class Sprite extends View
{
        public boolean onTouchEvent(MotionEvent event)
        {
            // do your movement logic
            return true; // return true if we are handling the event, false otherwise
        }
} 

Second way - do your touch processing in GameView. In this case GameView has to hold valid Sprite instance

public class Sprite extends View
{
    public void move(float x, float y)
    {
    // do your movement logic here 
    }
} 

public class GameView extends View
{
    public Sprite sprite; // you have to initialize that sprite instance before you can use it 
    // - most likely in Activity onCreate method, but that will depend on your game logic

    public boolean onTouchEvent(MotionEvent event)
    {
        sprite.move(event.GetX(), event.GetY());
        return true; // return true if we are handling the event, false otherwise
    }
}