【问题标题】:setContentView sets display blacksetContentView 设置显示黑色
【发布时间】:2018-10-15 05:49:51
【问题描述】:

会有很多代码。我不得不把它留给你理解应用程序的逻辑。 这是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 销毁(我在 onDestroy() 和 run() 方法结束时使用 Logs 检查了它们)。

【问题讨论】:

  • 我相信这应该有助于删除视图。 stackoverflow.com/a/7295641/6142219
  • 我不认为删除视图实际上是这里的问题,因为当我使用 DView 作为内容视图设置新的内容视图时,一切正常。
  • 这就是我想说的。新视图被初始化但没有被删除。它就像一张白板,你只去掉了纸,但你需要把整个黑板都去掉
  • 我还是不明白。那么为什么使用 DView 一切顺利呢?链接中显示的方法用于从其父对象中删除子对象。
  • 也许您需要像为 Dview 所做的那样重新实例化主视图。我的猜测是直到删除视图。但我刚刚读到 setContentView 替换了现有视图。

标签: java android setcontentview


【解决方案1】:

您正在从另一个类调用 Activity 的方法。代替 mainActivity.backToMenu(),创建一个接口,在 MainActivity 中实现它,并在 GameView 中传递引用来初始化接口。而在调用win方法的地方,调用接口方法,而不是调用MainActivity的公共方法。

创建一个界面,如:

public interface UpdateActivity{
    void updateActivity();
}

在主活动中

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-20
    • 2021-06-16
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多