如何在屏幕旋转上存储大量数据?
How to store lots of data upon Screen Rotation?
是的,我已经阅读了很多其他帖子,但我无法跟进,因为我有很多变量,而不仅仅是一两个。
我第一次制作支持横屏的应用程序(TIC TAC TOE)。我正在丢失有关屏幕旋转的数据。
package com.netlify.krupesh.tictactoe;
import android.graphics.Typeface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
// 0 for zero and 1 for X
// 2 for empty
boolean gameActive = true;
int[] gameState = {2,2,2,2,2,2,2,2,2};
int[][] winningPositions = {{0,1,2}, {3,4,5}, {6,7,8}, {0,3,6}, {1,4,7}, {2,5,8}, {0,4,8}, {2,4,6}};
int activePlayer = 0;
int[] playerScores = {0,0};
// Show Symbol on Tap
public void showSymbol(View view){
// Set Player Scores
TextView player1 = (TextView) findViewById(R.id.p1Score);
TextView player2 = (TextView) findViewById(R.id.p2Score);
player1.setText(playerScores[0]+"");
player2.setText(playerScores[1]+"");
// Get Symbol Info
ImageView symbol = (ImageView) view;
int tappedSymbol = Integer.parseInt(symbol.getTag().toString());
// Update Game state Array
if(gameState[tappedSymbol]==2 && gameActive) {
gameState[tappedSymbol] = activePlayer;
// Show Symbol with Animation
symbol.setAlpha(0f);
if (activePlayer == 0) {
symbol.setImageResource(R.drawable.zero);
activePlayer = 1;
showCurrentPlayer(2);
} else {
symbol.setImageResource(R.drawable.cross);
activePlayer = 0;
showCurrentPlayer(1);
}
symbol.animate().alpha(1).setDuration(400);
checkDraw(gameState);
for (int[] winningPosition : winningPositions) {
if (gameState[winningPosition[0]] == gameState[winningPosition[1]] && gameState[winningPosition[1]] == gameState[winningPosition[2]] && gameState[winningPosition[0]] != 2) {
showCurrentPlayer(0);
// Pause The Game
gameActive = false;
// Won the Game
String winningPlayer ;
if (gameState[winningPosition[0]] == 0) winningPlayer = "Player 1";
else winningPlayer = "Player 2";
Toast.makeText(this, winningPlayer + " won!", Toast.LENGTH_SHORT).show();
// Update Scores
playerScores[gameState[winningPosition[0]]]++;
player1.setText(playerScores[0] + "");
player2.setText(playerScores[1] + "");
}
}
}
}
public void resetBoard(View view){
android.support.v7.widget.GridLayout board = (android.support.v7.widget.GridLayout)findViewById(R.id.gridLayout);
for(int i=0; i<board.getChildCount(); i++) {
ImageView symbol = (ImageView) board.getChildAt(i);
symbol.setImageDrawable(null);
}
for(int i=0; i<gameState.length; i++ ){
gameState[i] = 2;
}
gameActive = true;
activePlayer = 0;
showCurrentPlayer(1);
}
public void checkDraw(int[] gamestate){
for(int i =0; i<gamestate.length; i++){
if(gamestate[i]==2){
return;
}
}
showCurrentPlayer(0);
Toast.makeText(this, "Match Draw!", Toast.LENGTH_SHORT).show();
}
public void resetAll(View view){
resetBoard(view);
playerScores[0]=0; playerScores[1]=0;
TextView player1 = (TextView) findViewById(R.id.p1Score);
TextView player2 = (TextView) findViewById(R.id.p2Score);
player1.setText(playerScores[0] + "");
player2.setText(playerScores[1] + "");
showCurrentPlayer(1);
}
public void showCurrentPlayer(int i){
TextView player1Heading = (TextView) findViewById(R.id.subheading1);
TextView player2Heading = (TextView) findViewById(R.id.subheading2);
if(i==1){
player1Heading.setTextColor(getResources().getColor(R.color.colorPlayer1));
player1Heading.setTypeface(null, Typeface.BOLD);
player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player2Heading.setTypeface(null, Typeface.NORMAL);
}
if(i==2){
player2Heading.setTextColor(getResources().getColor(R.color.colorPlayer2));
player2Heading.setTypeface(null, Typeface.BOLD);
player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player1Heading.setTypeface(null, Typeface.NORMAL);
}
if(i==0){
player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player1Heading.setTypeface(null, Typeface.NORMAL);
player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player2Heading.setTypeface(null, Typeface.NORMAL);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ===================== Hide Status Bar ========================== //
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// ================================================================ //
setContentView(R.layout.activity_main);
showCurrentPlayer(1);
}
}
看,有这么多东西.. 对于所有 ImageView,我需要保存谁设置了他们的图像。现在我该如何解决这个旋转问题??
添加代码片段的解决方案最有帮助,新手 Android 开发
@krupesh Anadkat 作为新手,我感到很沮丧,但 @CommonsWare 是一位经验丰富的开发人员,已经在游戏中玩了好几天了.
听从他的建议,确保你学习了他概述的基础知识,而不是盲目学习或只是为了它而匆忙构建一些东西。
然而今天是你的幸运日,所以我会用一些代码片段来宠坏你(我们千禧一代的程序员喜欢它简单 - 是的,我说过!!!)继续阅读并学习。
您在这里遇到的问题是设备配置更改。
在您的情况下,屏幕方向 发生了变化。
每次用户旋转该屏幕时,Android OS 都会重新创建您的 activity[=56= 】 一个新的。 Android OS 意味着没有任何危害,它只是试图提高效率,因为它检查是否有更好的资源用于新方向,如果有,它可以使用那些相反。
这就是你痛苦的根源。现在让我们开始并帮助你成为伙伴。
您可以使用 Activity 的 class 方法来解决这个问题。在全能的 Android OS 杀死你的 Activity 之前,方法 onSaveInstanceState() 将在你的Activity 的生命周期。在您的 class 中,您覆盖 onSaveInstanceState() 并将您想要的数据保存到 Bundle 其中 onSaveInstanceState() 作为参数。
然后在你的 Activity 的 onCreate() 你检查 savedInstanceState 是否不为空如果它不为空你检索您的数据。
不过要小心;最好将原始数据类型保存到Bundle或可序列化的对象以避免检索数据已过时,即已过时或不再有效。
请参阅下面我的 SaveDataAcrossScreenOrientation Activity 的代码片段
package com.demo.android.savedataacrossscreenrotationdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class SaveDataAcrossScreenOrientation extends AppCompatActivity {
// Key to be used for the key: value pair to be saved to the bundle
private static final String KEY_GREETING_TEXT = "greeting_text";
// The text currently displayed to the screen
private String mCurrentDisplayedText;
private TextView mGreetingTextView;
private Button mSpanishButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get references to the button and textview
mGreetingTextView = (TextView) findViewById(R.id.greeting_text_view);
mSpanishButton = (Button) findViewById(R.id.change_greeting_button);
// If mCurrentDisplayedText is inside the bundle retrieve and display it on screen
if(savedInstanceState != null) {
mCurrentDisplayedText = savedInstanceState.getString(KEY_GREETING_TEXT, "");
if (mCurrentDisplayedText != "") {
mGreetingTextView.setText(mCurrentDisplayedText);
}
}
// Set a listener on the spanish button
mSpanishButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Change the english text to spanish when the button is clicked
mGreetingTextView.setText(R.string.spanish_greeting);
// Get the text currently shown in the text view
mCurrentDisplayedText = (String) mGreetingTextView.getText(); // Calling getText() returns a CharSequence cast it to a string
}
});
}
// Override onSaveInstanceState(Bundle savedInstanceState) and save mCurrentDisplayedText to the bundle
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(KEY_GREETING_TEXT, mCurrentDisplayedText);
}
}
玩得开心!
是的,我已经阅读了很多其他帖子,但我无法跟进,因为我有很多变量,而不仅仅是一两个。
我第一次制作支持横屏的应用程序(TIC TAC TOE)。我正在丢失有关屏幕旋转的数据。
package com.netlify.krupesh.tictactoe;
import android.graphics.Typeface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
// 0 for zero and 1 for X
// 2 for empty
boolean gameActive = true;
int[] gameState = {2,2,2,2,2,2,2,2,2};
int[][] winningPositions = {{0,1,2}, {3,4,5}, {6,7,8}, {0,3,6}, {1,4,7}, {2,5,8}, {0,4,8}, {2,4,6}};
int activePlayer = 0;
int[] playerScores = {0,0};
// Show Symbol on Tap
public void showSymbol(View view){
// Set Player Scores
TextView player1 = (TextView) findViewById(R.id.p1Score);
TextView player2 = (TextView) findViewById(R.id.p2Score);
player1.setText(playerScores[0]+"");
player2.setText(playerScores[1]+"");
// Get Symbol Info
ImageView symbol = (ImageView) view;
int tappedSymbol = Integer.parseInt(symbol.getTag().toString());
// Update Game state Array
if(gameState[tappedSymbol]==2 && gameActive) {
gameState[tappedSymbol] = activePlayer;
// Show Symbol with Animation
symbol.setAlpha(0f);
if (activePlayer == 0) {
symbol.setImageResource(R.drawable.zero);
activePlayer = 1;
showCurrentPlayer(2);
} else {
symbol.setImageResource(R.drawable.cross);
activePlayer = 0;
showCurrentPlayer(1);
}
symbol.animate().alpha(1).setDuration(400);
checkDraw(gameState);
for (int[] winningPosition : winningPositions) {
if (gameState[winningPosition[0]] == gameState[winningPosition[1]] && gameState[winningPosition[1]] == gameState[winningPosition[2]] && gameState[winningPosition[0]] != 2) {
showCurrentPlayer(0);
// Pause The Game
gameActive = false;
// Won the Game
String winningPlayer ;
if (gameState[winningPosition[0]] == 0) winningPlayer = "Player 1";
else winningPlayer = "Player 2";
Toast.makeText(this, winningPlayer + " won!", Toast.LENGTH_SHORT).show();
// Update Scores
playerScores[gameState[winningPosition[0]]]++;
player1.setText(playerScores[0] + "");
player2.setText(playerScores[1] + "");
}
}
}
}
public void resetBoard(View view){
android.support.v7.widget.GridLayout board = (android.support.v7.widget.GridLayout)findViewById(R.id.gridLayout);
for(int i=0; i<board.getChildCount(); i++) {
ImageView symbol = (ImageView) board.getChildAt(i);
symbol.setImageDrawable(null);
}
for(int i=0; i<gameState.length; i++ ){
gameState[i] = 2;
}
gameActive = true;
activePlayer = 0;
showCurrentPlayer(1);
}
public void checkDraw(int[] gamestate){
for(int i =0; i<gamestate.length; i++){
if(gamestate[i]==2){
return;
}
}
showCurrentPlayer(0);
Toast.makeText(this, "Match Draw!", Toast.LENGTH_SHORT).show();
}
public void resetAll(View view){
resetBoard(view);
playerScores[0]=0; playerScores[1]=0;
TextView player1 = (TextView) findViewById(R.id.p1Score);
TextView player2 = (TextView) findViewById(R.id.p2Score);
player1.setText(playerScores[0] + "");
player2.setText(playerScores[1] + "");
showCurrentPlayer(1);
}
public void showCurrentPlayer(int i){
TextView player1Heading = (TextView) findViewById(R.id.subheading1);
TextView player2Heading = (TextView) findViewById(R.id.subheading2);
if(i==1){
player1Heading.setTextColor(getResources().getColor(R.color.colorPlayer1));
player1Heading.setTypeface(null, Typeface.BOLD);
player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player2Heading.setTypeface(null, Typeface.NORMAL);
}
if(i==2){
player2Heading.setTextColor(getResources().getColor(R.color.colorPlayer2));
player2Heading.setTypeface(null, Typeface.BOLD);
player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player1Heading.setTypeface(null, Typeface.NORMAL);
}
if(i==0){
player1Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player1Heading.setTypeface(null, Typeface.NORMAL);
player2Heading.setTextColor(getResources().getColor(R.color.colorHeading));
player2Heading.setTypeface(null, Typeface.NORMAL);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ===================== Hide Status Bar ========================== //
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// ================================================================ //
setContentView(R.layout.activity_main);
showCurrentPlayer(1);
}
}
看,有这么多东西.. 对于所有 ImageView,我需要保存谁设置了他们的图像。现在我该如何解决这个旋转问题??
添加代码片段的解决方案最有帮助,新手 Android 开发
@krupesh Anadkat 作为新手,我感到很沮丧,但 @CommonsWare 是一位经验丰富的开发人员,已经在游戏中玩了好几天了.
听从他的建议,确保你学习了他概述的基础知识,而不是盲目学习或只是为了它而匆忙构建一些东西。
然而今天是你的幸运日,所以我会用一些代码片段来宠坏你(我们千禧一代的程序员喜欢它简单 - 是的,我说过!!!)继续阅读并学习。
您在这里遇到的问题是设备配置更改。
在您的情况下,屏幕方向 发生了变化。
每次用户旋转该屏幕时,Android OS 都会重新创建您的 activity[=56= 】 一个新的。 Android OS 意味着没有任何危害,它只是试图提高效率,因为它检查是否有更好的资源用于新方向,如果有,它可以使用那些相反。
这就是你痛苦的根源。现在让我们开始并帮助你成为伙伴。
您可以使用 Activity 的 class 方法来解决这个问题。在全能的 Android OS 杀死你的 Activity 之前,方法 onSaveInstanceState() 将在你的Activity 的生命周期。在您的 class 中,您覆盖 onSaveInstanceState() 并将您想要的数据保存到 Bundle 其中 onSaveInstanceState() 作为参数。
然后在你的 Activity 的 onCreate() 你检查 savedInstanceState 是否不为空如果它不为空你检索您的数据。
不过要小心;最好将原始数据类型保存到Bundle或可序列化的对象以避免检索数据已过时,即已过时或不再有效。
请参阅下面我的 SaveDataAcrossScreenOrientation Activity 的代码片段
package com.demo.android.savedataacrossscreenrotationdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class SaveDataAcrossScreenOrientation extends AppCompatActivity {
// Key to be used for the key: value pair to be saved to the bundle
private static final String KEY_GREETING_TEXT = "greeting_text";
// The text currently displayed to the screen
private String mCurrentDisplayedText;
private TextView mGreetingTextView;
private Button mSpanishButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get references to the button and textview
mGreetingTextView = (TextView) findViewById(R.id.greeting_text_view);
mSpanishButton = (Button) findViewById(R.id.change_greeting_button);
// If mCurrentDisplayedText is inside the bundle retrieve and display it on screen
if(savedInstanceState != null) {
mCurrentDisplayedText = savedInstanceState.getString(KEY_GREETING_TEXT, "");
if (mCurrentDisplayedText != "") {
mGreetingTextView.setText(mCurrentDisplayedText);
}
}
// Set a listener on the spanish button
mSpanishButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Change the english text to spanish when the button is clicked
mGreetingTextView.setText(R.string.spanish_greeting);
// Get the text currently shown in the text view
mCurrentDisplayedText = (String) mGreetingTextView.getText(); // Calling getText() returns a CharSequence cast it to a string
}
});
}
// Override onSaveInstanceState(Bundle savedInstanceState) and save mCurrentDisplayedText to the bundle
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(KEY_GREETING_TEXT, mCurrentDisplayedText);
}
}
玩得开心!