Yesterday I asked this question on the network about how to resume a simple Tic-tac-toe game after closing and opening the fragment. As I said in my question:
I'm learning Android development by creating a test project: Tic-tac-toe. My Tic-tac-toe app starts with a Main Menu activity with a Button that says New Game. After clicking New Game, an activity with a fragment containing a Tic-Tac-Toe game (in a GridLayout) launches. The user can play the game, but when they go back to the Main Menu, the game state is not saved.
I want to change this so that when the user goes back to the Main Menu, they will see a new Button called "Continue" (in addition to the "New Game" Button). Once the user clicks "Continue", the game they were playing before continues. If the click the "New Game" button, a new game will be launched like before.
Three answers were proposed with two different methods: Utilizing SharedPreferences
or using startActivityForResult()
. Both of those methods seem to work fine, but I stumbled upon a cleaner solution, by just declaring the Tic-Tac-Toe object as static:
public static TicTacToe t = new TicTacToe();
This appears to do everything I need since now I will only have one instance of t
no matter how often I create or destroy the fragment. So on orientation changes, going back to Main Menu and opening the game again, or even on closing and restarting the app, the game state stays the same just like I wanted. However, since nobody proposed this solution and because I am a novice in Android development, I must ask: is there something wrong with using this method?
Here is my full code, with only that single change made:
My MainMenu
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);
}
}
with a corresponding xml file activity_main_game
:
<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>
Now my MainGame.class
looks like this:
public class MainGame extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_game);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new BoardFragment()).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_game, 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 static class BoardFragment extends Fragment {
public static TicTacToe t = new TicTacToe(); //A class I wrote that launches a simple TicTacToe game
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
t = new TicTacToe(savedInstanceState.getInt("TicTacToeData"),
);
}
//Graphics stuff here: variable rootView which contains the TicTacToe grid is defined
//and onClickListeners are added to the ImageViews in the GridLayout which makes corresponding
//changes to t.
return rootView;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("TicTacToeData", t.getGameData());
}
}
}