android - 如何在屏幕旋转时存储大量数据?
问题描述
是的,我已经阅读了许多其他帖子,但我无法跟进,因为我有很多变量,而不仅仅是一两个。
我第一次使用横向支持制作应用程序(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);
}
}
看,有很多东西.. 对于所有 ImageViews,我需要保存设置了图像的人。现在我该如何解决这个旋转问题?
添加代码片段的解决方案是最有帮助的,Android 开发新手
解决方案
@krupesh Anadkat我作为新手感到沮丧,但@CommonsWare是一位经验丰富的开发人员,他已经在游戏中工作了好几天。
听从他的建议,确保你学习了他概述的基础知识,而不是为了它而匆匆忙忙地建造一些东西。
然而今天是你的幸运日,所以我会用一些代码片段来宠爱你(我们千禧一代的程序员喜欢它很容易——是的,我说过!!!)阅读和学习。
您在这里面临的问题是设备配置更改。
在您的情况下,屏幕方向发生了变化。
每次用户旋转该屏幕时,Android 操作系统都会重新创建一个新的活动。Android OS没有任何害处,它只是试图提高效率,因为它会检查是否有更好的资源用于该新方向,如果有,它可以使用这些资源。
这是你痛苦的根源。现在让我们继续努力并帮助您解决问题。
您可以使用Activity 的类方法来解决这个问题。在全能的Android 操作系统杀死你的 Activity 之前,方法onSaveInstanceState()将在你的 Activity 的生命周期中被调用。在您的课程中,您覆盖onSaveInstanceState()并将您想要的数据保存到onSaveInstanceState()作为参数的Bundle中。
然后在您的 Activity 的onCreate()中检查savedInstanceState是否不为空,如果它不为空,则您检索数据。
不过要小心;最好将原始数据类型保存到Bundle或可序列化的对象中,以避免检索过时的数据,即过期或不再有效的数据。
请参阅下面我的 SaveDataAcrossScreenOrientation 活动的代码片段
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);
}
}
玩得开心!
推荐阅读
- linux - Chef 错误:无法完成 #verify 操作:[undefined method `[]' for nil:NilClass] on default-amazonlinux2-base
- python - 为什么socket io客户端不工作?
- html - 如何在 Angular 中实现指令(ng-template)?
- python - Django 究竟什么时候运行查询?
- swift - 拉动刷新 Swift 中的新项目
- rust - Rust 未解决的模块
- amazon-web-services - 如何创建 lambda boto3 函数以在另一个 Aws 帐户中创建 cloudformation 堆栈
- powershell - 使用 Read-Host 运行 Compress-Archive
- list - list() 在一行中,不能引入 /newlines
- python - 在 python 中将二进制数据转换为 JSON 时,如何去除多余的行和空格?