Будет много кода. Мне пришлось оставить это для понимания логики приложения. Вот файл 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 ()).
Я не думаю, что удаление представлений на самом деле является проблемой, поскольку, когда я устанавливаю новое представление содержимого с DView в качестве представления содержимого, все работает нормально.
вот что я пытаюсь сказать. новое представление инициализируется, но не удаляется. Это как чистый лист, с которого вы удалили только бумагу, но вам нужно удалить всю доску.
Я все еще не понимаю. Почему тогда с DView все пошло гладко? И метод, показанный в ссылке, используется для удаления дочернего объекта из его родительского.
возможно, вам нужно повторно создать экземпляр основного представления, как вы это делали для Dview. Я предполагаю, что до удаления просмотров. но я только что прочитал, что setContentView заменяет существующее представление.




Вы вызываете метод 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();
Я считаю, что это должно помочь в удалении просмотров. stackoverflow.com/a/7295641/6142219