在位图图像上设置 onClickListener 会引发错误

Setting up onClickListener on bitmap images throws error

我开始在我的 android 游戏(flappy bird 类型的克隆游戏)中实现触摸控制,但我很难完成这项工作。我已经实现了 onTouchEvent,它基本上占据了整个屏幕并对任何触摸做出反应,但现在我想扩展它并具有可点击的 buttons/icons 等。我了解了应该完成这项工作的 OnClickListener 函数,但我被困在了地狱这,游戏现在在初始化后崩溃。

根据我的研究,我已将我的播放按钮(PNG 图像)设置为 ImageBitmap,然后将其设置为 OnClickListener,目前我只是在测试它以给我一些控制台。在 MainActivity 中,我还按照建议使用 findViewById 设置了 ImageButton。 Android Studio 中没有错误,但在 运行:

之后出现
2020-05-11 21:23:34.526 6075-6075/com.markS.flappykillercrow E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.markS.flappykillercrow, PID: 6075
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.markS.flappykillercrow/com.markS.flappykillercrow.MainActivity}: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.markS.flappykillercrow.GameManager
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.markS.flappykillercrow.GameManager
     Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class com.markS.flappykillercrow.GameManager
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:419)
        at android.app.Activity.setContentView(Activity.java:2669)
        at com.markS.flappykillercrow.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setImageBitmap(android.graphics.Bitmap)' on a null object reference
        at com.markS.flappykillercrow.sprites.GameOver.<init>(GameOver.java:33)
        at com.markS.flappykillercrow.GameManager.initGame(GameManager.java:86)
        at com.markS.flappykillercrow.GameManager.<init>(GameManager.java:75)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:647) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
        at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:419) 
        at android.app.Activity.setContentView(Activity.java:2669) 
        at com.markS.flappykillercrow.MainActivity.onCreate(MainActivity.java:24) 
        at android.app.Activity.performCreate(Activity.java:7009) 
        at android.app.Activity.performCreate(Activity.java:7000) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

这是 class 我用 OnClickListener 实现播放按钮的地方:

package com.markS.flappykillercrow.sprites;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

import com.markS.flappykillercrow.MainActivity;
import com.markS.flappykillercrow.R;

public class GameOver implements Sprite {
    private Bitmap gameOver;
    private Bitmap playButton;   //adding playButton Bitmap
    private Bitmap rateUs;
    private Bitmap volumeOn;
    private Bitmap volumeOf;
    private ImageButton imgButton;

    private int screenHeight, screenWidth;

    public GameOver(Resources resources, int screenHeight, int screenWidth) {
        this.screenHeight = screenHeight;
        this.screenWidth = screenWidth;
        gameOver = BitmapFactory.decodeResource(resources, R.drawable.gameover);

        playButton = BitmapFactory.decodeResource(resources, R.drawable.playbutton);
        imgButton.setImageBitmap(playButton);
        imgButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("THIS WORKS");
            }
        });

        rateUs = BitmapFactory.decodeResource(resources, R.drawable.rateus);
        volumeOn = BitmapFactory.decodeResource(resources, R.drawable.volumeon);
        volumeOf = BitmapFactory.decodeResource(resources, R.drawable.volumeoff);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawBitmap(gameOver, screenWidth / 2 - gameOver.getWidth() / 2, screenHeight / 4, null);
    }

    //for drawing playbutton
    public void drawplay(Canvas canvas) {
        canvas.drawBitmap(playButton, (screenWidth / 2 - playButton.getWidth() / 2), screenHeight / (float) 2.5, null);
    }

    //for drawing rate us
    public void drawrateus(Canvas canvas) {
        canvas.drawBitmap(rateUs, (float) (screenWidth / 1.4 - rateUs.getWidth() / 21.7), screenHeight / (float) 3.2, null);
    }

    //for drawing volumes
    public void drawvolumeon(Canvas canvas) {
        canvas.drawBitmap(volumeOn, (screenWidth / 23 - volumeOn.getWidth() / 23), screenHeight / 50, null);
    }

    //later implement if statement
    public void drawvolumeof(Canvas canvas) {
        canvas.drawBitmap(volumeOf, (screenWidth / 20 - volumeOf.getWidth() / 20), screenHeight / 50, null);
    }

    @Override
    public void update() {
    }
}

主要活动:

package com.markS.flappykillercrow;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.widget.ImageButton;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;

public class MainActivity extends Activity {
    private AdView nAdView;
    private ImageButton imgButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main);
        imgButton=(ImageButton) findViewById(R.id.imgButton);

        MobileAds.initialize(this,"ca-app-pub-9057526686789846~7828440247"); //just a test ID
        nAdView=findViewById(R.id.adView);
        AdRequest adRequest=new AdRequest.Builder().build();
        nAdView.loadAd(adRequest);
    }
}

感谢大家提供的有用建议。我想一旦我得到 "sout" 控制台工作,我就可以从那里进行管理,但现在我被困得太久了。谢谢!

您的回溯中的相关(原始)错误:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setImageBitmap(android.graphics.Bitmap)' on a null object reference

您需要初始化imgButton