无法从android中的子级更新文本视图

问题描述 投票:0回答:1

我发现了一个非常讨厌的问题。我在android中制作吃豆人。游戏活动有一些孩子,最重要的两个是GameView(位于SurfaceView中)和TextView,当吃豆子吃托盘,水果或其他类似事件时,TextView应该更新。话虽如此,让我们详细看看。

首先是PlayActivity代码

package com.example.pacman;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class PlayActivity extends AppCompatActivity {
    private TextView playerNickname;
    private TextView score;
    private TextView maxScore;
    private SurfaceView gameSurfaceView;
    private GameView gameView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Modified code
        setContentView(R.layout.activity_game);
        //we get text view that we will use
        playerNickname=(TextView) this.findViewById(R.id.tv_player);
        score=(TextView) this.findViewById(R.id.tv_current_score);
        maxScore=(TextView) this.findViewById(R.id.tv_current_max_score);
        gameSurfaceView= (GameView) this.findViewById(R.id.game_view);

        //set text view initial values
        playerNickname.setText(getIntent().getExtras().getString("playerNickname"));
        score.setText("0");

        maxScore.setText("To modify");

        this.gameView=new GameView(gameSurfaceView.getContext());
        this.gameView.setScoreTv(this);
        this.gameSurfaceView.getHolder().addCallback(this.gameView);
    }

    protected void onResume(){
        super.onResume();
        this.gameView.resume();
    }

    protected void onPause(){
        super.onPause();
        this.gameView.pause();
    }
}

现在带有构造函数的Gamview和

package com.example.pacman;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback, GestureDetector.OnGestureListener {
    private static final float SWIPE_THRESHOLD = 2;
    private static final float SWIPE_VELOCITY = 2;
    private GestureDetector gestureDetector;

    private Thread thread; //game thread

    private TextView scoreTv;
    private double score;
    private Semaphore drawSemaphore;


    private int[][] map;
    private CountdownBonusThread bonusCounter;
    private int xPosBonus; //Added
    private int yPosBonus; //Added
    private int bonusResetTime = 5000;
    private boolean bonusAvailable;

    private SurfaceHolder holder;
    private boolean canDraw = false;

    private Paint paint;

    private List<Node> path;

    private int screenWidth;                // Ancho de la pantalla
    private int blockSize;
    private static int movementFluencyLevel=8; //this movement should be a multiple of the blocksize, if note the pacman will pass walls

    private CountdownGhostsState stateCounter;


    private Ghost[] ghosts = new Ghost[4];

    private Bitmap[] pacmanRight, pacmanDown, pacmanLeft, pacmanUp;
    private Bitmap cherryBitmap;

    int[] pacmanPos;

    private int totalFrame = 4;             // Cantidad total de animation frames por direccion
    private int currentPacmanFrame = 0;     // animation frame de pacman actual
    private int currentArrowFrame = 0;      // animation frame de arrow actual
    private long frameTicker;               // tiempo desde que el ultimo frame fue dibujado

    private char direction = ' ';              // direccion del movimiento, movimiento inicial nulo
    private char nextDirection = ' ';          // Buffer para la siguiente direccion de movimiento tactil
    private char viewDirection = 'd';          // Direccion en la que pacman esta mirando


    public GameView(Context context) {
        super(context);
        this.constructorHelper();
    }

    private void constructorHelper() {
        this.gestureDetector = new GestureDetector(this);
        this.setFocusable(true);
        this.holder = getHolder();
        this.holder.addCallback(this);
        this.frameTicker = (long) (1000.0f / totalFrame);

        this.map=this.loadOriginalMap();

        this.screenWidth = getResources().getDisplayMetrics().widthPixels;
        this.blockSize = ((this.screenWidth/this.map[0].length)/movementFluencyLevel)*movementFluencyLevel;
        this.holder.setFixedSize(blockSize*this.map[0].length,blockSize*this.map.length);
        this.map=loadOriginalMap();

        paint = new Paint();
        paint.setColor(Color.WHITE);
        this.score=0;

        this.pacmanPos=new int[2];
        this.pacmanPos[0]=14*blockSize; //posX
        this.pacmanPos[1]=23*blockSize; //posY

        bonusCounter = new CountdownBonusThread(this);
        loadBitmapImages();
}

    public void setScoreTv(Context parentContext) {
        this.scoreTv=(TextView) ((Activity) parentContext).findViewById(R.id.tv_current_score);
    }

在游戏视图的最后一个方法中,分配为null,结果是当我尝试编辑文本时显示下一条消息:

E / AndroidRuntime:致命例外:线程5

处理:com.example.pacman,PID:12235

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'void android.widget.TextView.setText(java.lang.CharSequence)'

在com.example.pacman.GameView.movePacman(GameView.java:227)]中>

在com.example.pacman.GameView.run(GameView.java:163)]中>

在java.lang.Thread.run(Thread.java:919)

我不理解为什么如果我给setTextView分配了发送父级上下文,有什么建议吗?

有趣的文章:我已经找到了,但是仅适用于片段https://blog.codeonion.com/2015/10/03/android-how-to-fix-null-object-reference-error/

我认为问题是我需要该活动,但是getActivity方法不属于AppCompatActivity接口的一部分

我发现了一个非常讨厌的问题。我在android中制作吃豆人。游戏活动有一些子级,最重要的两个是GameView(位于SurfaceView中)和TextView,它们应为...

android textview parent-child surfaceview inflate
1个回答
0
投票

而不是将上下文传递给setScoreTV(Context ..)您可以传递已经拥有的参考textView。

在PlayActivity中,您获得了textView参考:

© www.soinside.com 2019 - 2024. All rights reserved.