关闭碎片后,在Android中恢复Tic tac toe游戏

关闭碎片后,在Android中恢复Tic tac toe游戏,android,android-fragments,Android,Android Fragments,我通过创建一个测试项目来学习Android开发:Tic-tac-toe。我的Tic tac toe应用程序以一个主菜单活动开始,该活动带有一个显示新游戏的按钮。单击“新建游戏”后,将启动一个包含Tic Tac Toe游戏片段的活动(在网格布局中)。用户可以玩游戏,但当他们返回主菜单时,游戏状态不会保存 我想对此进行更改,这样当用户返回主菜单时,他们将看到一个名为“继续”的新按钮(除了“新游戏”按钮之外)。一旦用户单击“继续”,他们之前玩的游戏将继续。如果点击“新游戏”按钮,新游戏将像以前一样启动

我通过创建一个测试项目来学习Android开发:Tic-tac-toe。我的Tic tac toe应用程序以一个主菜单活动开始,该活动带有一个显示新游戏的
按钮。单击“新建游戏”后,将启动一个包含Tic Tac Toe游戏片段的活动(在网格布局中)。用户可以玩游戏,但当他们返回主菜单时,游戏状态不会保存

我想对此进行更改,这样当用户返回主菜单时,他们将看到一个名为“继续”的新
按钮(除了“新游戏”按钮之外)。一旦用户单击“继续”,他们之前玩的游戏将继续。如果点击“新游戏”按钮,新游戏将像以前一样启动

通过使用
onSaveInstanceState
方法和
Bundle
savedInstanceState
,我能够在方向更改时保留游戏状态(通过保存底层Tictoe类的数据)。下面的代码显示了我是如何做到这一点的。这次我想再做一次类似的事情——我读过,但我不太明白最好的开始方式。谁能告诉我正确的步骤吗

请注意,我是以编程方式完成这项工作的(即在xml文件之外设计布局)

我的
main菜单
class:

public class MainMenu extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_menu);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void startGame(View view) {
        Intent intent = new Intent(this,MainGame.class);
        startActivity(intent);
    }

}
使用相应的xml文件
活动\u主\u游戏

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/new_game"
        android:onClick="startGame"

        />

</RelativeLayout>
谢谢您的帮助。

您有两个选择

  • SharedReferences
    :您可以使用shaerdPreferences存储游戏状态。它也将在应用程序重新启动后存储
  • 使用
    startActivityForResult()
    开始游戏活动,并在父活动上实现
    onActivityResult
    你有两个选择

  • SharedReferences
    :您可以使用shaerdPreferences存储游戏状态。它也将在应用程序重新启动后存储
  • 使用
    startActivityForResult()
    开始游戏活动,并在父活动上实现
    onActivityResult

    一种可能的解决方案是让您的
    MainGame
    活动在游戏结束时返回游戏状态。然后,您的
    主菜单
    活动可以保存该值,并使用该值在相同状态下启动游戏

    对于初学者,您希望以一种能够返回值的方式启动游戏活动:

    public class MainMenu extends ActionBarActivity {
    
        ...
    
        public void startGame() {
            Intent intent = new Intent(this, MainGame.class);
            startActivityForResult(intent, 1);
        }
    }
    
    接下来,您需要确保无论何时关闭,您的电路板碎片都返回正确的状态:

    public class BoardFragment extends Fragment {
    
        ...
    
        @Override
        public void onPause() {
            Intent result = new Intent();
            result.putExtra("TicTacToeData", t.getGameData());
            getActivity().setResult(Activity.RESULT_OK, result);
        }
    }
    
    之后,您需要菜单活动记录结果:

    public class MainMenu extends ActionBarActivity {
        private int mPreviousGameState;
    
        ...
    
        @Override
        protected void onActivityResult (int requestCode, int resultCode, Intent data) {
            if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
                mPreviousGameState = 1;
            }
        }
    }
    
    现在,您可以在开始游戏活动时通过此状态:

    public class MainMenu extends ActionBarActivity {
    
        ...
    
        public void continueGame() {
            Intent intent = new Intent(this, MainGame.class);
            intent.putExtra("TicTacToeData", mPreviousGameState);
            startActivityForResult(intent, 1);
        }
    }
    
    现在,您需要一种方法来创建已处于特定游戏状态的棋盘:

    public class BoardFragment extends Fragment {
        public TicTacToe t = null
    
        ...
    
        public BoardFragment (int gameState) {
            t = new TicTacToe(gameState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            if (savedInstanceState != null) {
                // recreate the board after an orientation change
                t = new TicTacToe(savedInstanceState.getInt("TicTacToeData"));
            } else if (t == null) {
                // create a new board if this is a new game
                // if this is a continued game, the board is already setup
                t = new TicTacToe();
            }
    }
    
    最后,您需要从游戏中调用正确版本的
    BoardFragment

    public class MainGame extends ActionBarActivity {
    
        ...
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main_game);
            if (savedInstanceState == null) {
                Intent intent = getIntent();
                int gameState = intent.getIntExtra("TicTacToeData", -1);
                if (gameState == -1) {
                    getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment()).commit();
                } else {
                    getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment(gameState)).commit();
                }
            }
        }
    }
    

    一种可能的解决方案是让您的
    MainGame
    活动在游戏结束时返回游戏状态。然后,您的
    主菜单
    活动可以保存该值,并使用该值在相同状态下启动游戏

    对于初学者,您希望以一种能够返回值的方式启动游戏活动:

    public class MainMenu extends ActionBarActivity {
    
        ...
    
        public void startGame() {
            Intent intent = new Intent(this, MainGame.class);
            startActivityForResult(intent, 1);
        }
    }
    
    接下来,您需要确保无论何时关闭,您的电路板碎片都返回正确的状态:

    public class BoardFragment extends Fragment {
    
        ...
    
        @Override
        public void onPause() {
            Intent result = new Intent();
            result.putExtra("TicTacToeData", t.getGameData());
            getActivity().setResult(Activity.RESULT_OK, result);
        }
    }
    
    之后,您需要菜单活动记录结果:

    public class MainMenu extends ActionBarActivity {
        private int mPreviousGameState;
    
        ...
    
        @Override
        protected void onActivityResult (int requestCode, int resultCode, Intent data) {
            if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
                mPreviousGameState = 1;
            }
        }
    }
    
    现在,您可以在开始游戏活动时通过此状态:

    public class MainMenu extends ActionBarActivity {
    
        ...
    
        public void continueGame() {
            Intent intent = new Intent(this, MainGame.class);
            intent.putExtra("TicTacToeData", mPreviousGameState);
            startActivityForResult(intent, 1);
        }
    }
    
    现在,您需要一种方法来创建已处于特定游戏状态的棋盘:

    public class BoardFragment extends Fragment {
        public TicTacToe t = null
    
        ...
    
        public BoardFragment (int gameState) {
            t = new TicTacToe(gameState);
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            if (savedInstanceState != null) {
                // recreate the board after an orientation change
                t = new TicTacToe(savedInstanceState.getInt("TicTacToeData"));
            } else if (t == null) {
                // create a new board if this is a new game
                // if this is a continued game, the board is already setup
                t = new TicTacToe();
            }
    }
    
    最后,您需要从游戏中调用正确版本的
    BoardFragment

    public class MainGame extends ActionBarActivity {
    
        ...
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main_game);
            if (savedInstanceState == null) {
                Intent intent = getIntent();
                int gameState = intent.getIntExtra("TicTacToeData", -1);
                if (gameState == -1) {
                    getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment()).commit();
                } else {
                    getSupportFragmentManager().beginTransaction().add(R.id.container, new BoardFragment(gameState)).commit();
                }
            }
        }
    }
    

    你必须做两件事:

  • 当主游戏活动关闭时,在主类中获得通知
  • 更新UI以更改按钮文本
  • 在主类中获得通知:

    您可以使用
    startActivityForResult
    而不是
    startActivity
    启动
    main游戏
    活动。然后覆盖主类上的
    onActivityResult
    方法,以便在用户关闭
    Main游戏时收到通知

    此外,当用户单击“上一步”按钮时,您还必须修改
    MainGame
    以调用
    setResult(int-resultCode,Intent-data)
    setResult(int-resultCode)
    方法(取决于您是否希望将其他数据传递回活动)

    重写
    MainGame
    类中的onBackPressed()方法以调用setResult方法

    public void onBackPressed() {
        setResult(RESULT_OK);
        super.onBackPressed(); // otherwise your Activity won't be closed
    }
    
    请看一个更详细的示例

    更新用户界面:

  • 将按钮另存为局部变量(在onCreate方法中)
  • 更新按钮文本
    main游戏
    活动

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // Update the button text to "Continue"
             } else {
                 // Change the button text back to "New Game"
             }
         }
     }
    

  • 你必须做两件事:

  • 当主游戏活动关闭时,在主类中获得通知
  • 更新UI以更改按钮文本
  • 在主类中获得通知:

    您可以使用
    startActivityForResult
    而不是
    startActivity
    来启动
    MainGame
    活动。然后覆盖主类上的
    onActivityResult
    方法,以便在用户关闭
    MainGame
    时收到通知

    此外,当用户单击“上一步”按钮时,您还必须修改
    MainGame
    以调用
    setResult(int-resultCode,Intent-data)
    setResult(int-resultCode)
    方法(取决于您是否希望将其他数据传递回活动)

    重写
    MainGame
    类中的onBackPressed()方法以调用setResult方法

    public void onBackPressed() {
        setResult(RESULT_OK);
        super.onBackPressed(); // otherwise your Activity won't be closed
    }
    
    请看一个更详细的示例

    更新用户界面:

  • 将按钮另存为局部变量(在onCreate方法中)
  • 更新按钮文本
    main游戏
    活动

     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PICK_CONTACT_REQUEST) {
             if (resultCode == RESULT_OK) {
                 // Update the button text to "Continue"
             } else {
                 // Change the button text back to "New Game"
             }
         }
     }
    
  • 另一个s