setContentView устанавливает отображение черного - PullRequest
0 голосов
/ 04 мая 2018

Там будет много кода. Мне пришлось оставить это для вас, чтобы понять логику приложения. Вот основная деятельность. Вызывается при запуске.

public class MainActivity extends AppCompatActivity {

    private GameView gameView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //some unnecessary code
        setContentView(R.layout.activity_main);
    }

    public void startSurvival(View view) {
        gameView = new GameView(this, this, "survival");
        setContentView(gameView);
    }

    public void chooseData(View view){
        setContentView(new DView(this, this));
    }

    public void backToMenu(){
        setContentView(R.layout.activity_main);
        gameView = null;
    }

    @Override
    protected void onResume() {
        super.onResume();
        try {
            gameView.update();
        } catch (NullPointerException e) {}
    }
}

Эта активность представляет собой список параметров. Вы выбираете один, а затем GameView устанавливает в качестве содержимого просмотра с соответствующими параметрами. Здесь нет вопросов, поэтому я вырезал почти весь код.

public class DView extends ListView {

    DView(final Context context, final MainActivity mainActivity){
        super(context);

        this.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String[] columns = {"data"};
                String having = "id = " + ids[position];

                SQLiteDatabase db = dbHelper.getWritableDatabase();
                Cursor cursor = db.query("levels", columns, null, null, ID, having, null);

                if (cursor.moveToFirst()){
                    int dataInd = cursor.getColumnIndex(DATA);
                    mainActivity.setContentView(new GameView(context, mainActivity, cursor.getString(dataInd)));
                }//everything here works fine. This just shows that setContentView can be done multiple times 
        //without bugs 
                cursor.close();
                dbHelper.close();

            }
        });
    }
}

И тут возникает проблема. Когда вызывается метод win (), дисплей становится черным. Приложение не падает.

public class GameView extends SurfaceView{

    public MainActivity mainActivity;
    GameThread gameThread;
    public Player player = null;
    public Canvas canvas;
    public ExtraData data;

    public GameView (Context context, MainActivity mainActivity, String data){
        super(context);
        this.mainActivity = mainActivity;
        if (data.equals("survival")) {
            this.data = new ExtraData("RandomSpawn47",null, this);
        } else {
            this.data = new ExtraData("UsingData", data, this);
        }
        update();
    }

    void update(){
        gameThread = new GameThread(this);
        getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                gameThread.running(true);
                if (gameThread.getState() == Thread.State.NEW)
                    gameThread.start();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                gameThread.running(false);
            }
        });
        if (player == null)
            player = new Player(this);
    }

    public class GameThread extends Thread{
        private GameView gameView;

        public GameThread(GameView gameView) {
            this.gameView = gameView;
        }
            public void running(boolean run){
                running = run;
        }

        @Override
        public void run() {
            while (running){
                 canvas = null;
                try{
                    canvas = gameView.getHolder().lockCanvas(null);
                    synchronized (gameView.getHolder()){
                        draw(canvas);
                        this.wait(45);
                    }
                } catch(Exception e) {}
                finally {
                    if((canvas != null)&&(running)){
                        gameView.getHolder().unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
    }
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawColor(Color.BLUE);
        data.onDraw();
    }

    public void win(){
        mainActivity.backToMenu();//not switching the menu
    }
}

Другие классы, такие как ExtraData и Player, не важны.

Уничтожает GameThread и SurfaceView (я проверял их с помощью Logs в onDestroy () и в конце метода run ()).

1 Ответ

0 голосов
/ 04 мая 2018

Вы вызываете метод Activity из другого класса. Вместо mainActivity.backToMenu () создайте один интерфейс, внедрите его в MainActivity и передайте ссылку в GameView для инициализации интерфейса. А если вы вызываете метод win, вызывайте метод интерфейса вместо вызова открытого метода MainActivity.

Создайте один интерфейс, например:

public interface UpdateActivity{
    void updateActivity();
}

В MainActivity

public class MainActivity extends AppCompatActivity implements UpdateActivity

затем переопределить метод интерфейса

void updateActivity(){
        setContentView(R.layout.activity_main);
        gameView = null;
}

Передайте ссылку в GameView вместо передачи ссылки MainActivity.

    public GameView (Context context, UpdateActivity updateActivity , String data) {
        super(context);
        this.updateActivity = updateActivity ;
        if (data.equals("survival")) {
            this.data = new ExtraData("RandomSpawn47",null, this);
        } else {
            this.data = new ExtraData("UsingData", data, this);
        }
        update();
    }

Теперь вызовите метод, для которого вы хотите вызвать:

updateActivity.updateActivity();
...