SetContentView устанавливает черный экран

Будет много кода. Мне пришлось оставить это для понимания логики приложения. Вот файл MainActivity. Вызывается при запуске.

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 ()).

Я считаю, что это должно помочь в удалении просмотров. stackoverflow.com/a/7295641/6142219

Deepak kaku 04.05.2018 19:19

Я не думаю, что удаление представлений на самом деле является проблемой, поскольку, когда я устанавливаю новое представление содержимого с DView в качестве представления содержимого, все работает нормально.

user9686432 04.05.2018 23:24

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

Deepak kaku 04.05.2018 23:45

Я все еще не понимаю. Почему тогда с DView все пошло гладко? И метод, показанный в ссылке, используется для удаления дочернего объекта из его родительского.

user9686432 05.05.2018 00:46

возможно, вам нужно повторно создать экземпляр основного представления, как вы это делали для Dview. Я предполагаю, что до удаления просмотров. но я только что прочитал, что setContentView заменяет существующее представление.

Deepak kaku 05.05.2018 01:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
112
1

Ответы 1

Вы вызываете метод 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();

Другие вопросы по теме