在 screens/activities Android 应用程序之间移动时保存 UI 状态
Saving UI state when moving between screens/activities Android app
我正在做一个多屏问答应用。对于每个问题,我都有一个单独的 activity / 屏幕。在每个屏幕的底部都有 next/previous "buttons" 导航到 next/previous 屏幕。请查看带有问题的屏幕 UI 示例:
不过我有一个问题。假设用户选择问题 2 的答案,然后单击 "Previous",选择问题 1 的答案并单击 "Next"。
我想保存问题 2 的 UI 状态,这样,如果用户通过单击上一个或下一个返回问题,所选答案将保留。
我设法完成的一件事是当用户单击 "previous" 时 UI 保持不变,我在清单文件中使用了以下代码:
android:launchMode="singleTask"
但是,当用户通过 "next" 提出问题时,我无法保存它。这是我的 activity 问题 2 的代码:
package com.example.justynagolawska.quizappiteration2;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
public class Question2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
ActionBar actionbar = getSupportActionBar();
// Applies the custom action bar style
getSupportActionBar().setDisplayOptions(actionbar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.action_bar);
// Changes the action bar title
TextView title = (TextView) getSupportActionBar().getCustomView().findViewById(R.id.action_bar_title);
title.setText(R.string.q2_name);
//Getting the intent with score for question 1
Intent question2Intent = getIntent();
final int resultQ1 = question2Intent.getIntExtra("q1result", 0);
// Find the View that shows the next TextView
TextView nextQuestion = (TextView) findViewById(R.id.next);
// Set a click listener on that View
nextQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
//Calculate Question 2 score
int resultQ2 = calculateResultQ2(isCheckBox1Q2, isCheckBox2Q2, isCheckBox3Q2);
Intent question3Intent = new Intent(Question2Activity.this, Question3Activity.class);
question3Intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
question3Intent.putExtra ("q1result", resultQ1);
question3Intent.putExtra ("q2result", resultQ2);
startActivity(question3Intent);
}
});
// Find the View that shows the next TextView
TextView previousQuestion = (TextView) findViewById(R.id.previous);
// Set a click listener on that View
previousQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
Intent question1Intent = new Intent(Question2Activity.this, Question1Activity.class);
startActivity(question1Intent);
}
});
}
/**
* Check which checkbox was selected in the question 2
*
* @param checkBox1 is whether or not the user checked the checkbox1
* @param checkBox2 is whether or not the user checked the checkbox2
* @param checkBox3 is whether or not the user checked the checkbox3
* @return the score the user got for question 2
*/
private int calculateResultQ2(boolean checkBox1, boolean checkBox2, boolean checkBox3) {
int result = 0;
if (checkBox1 && checkBox2 && checkBox3) {
result = 1;
}
return result;
}
如果有人能帮助我,我将不胜感激。谢谢!
编辑: 下面是我使用 sharedPreferences 的工作代码,@tahsinRupam
提出的解决方案
package com.example.justynagolawska.quizappiteration2;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
public class Question2Activity extends AppCompatActivity {
SharedPreferences mypref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
final CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
final CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
final CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
mypref = PreferenceManager.getDefaultSharedPreferences(this);
ActionBar actionbar = getSupportActionBar();
// Applies the custom action bar style
getSupportActionBar().setDisplayOptions(actionbar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.action_bar);
// Changes the action bar title
TextView title = (TextView) getSupportActionBar().getCustomView().findViewById(R.id.action_bar_title);
title.setText(R.string.q2_name);
//Getting the intent with score for question 1
Intent question2Intent = getIntent();
final int resultQ1 = question2Intent.getIntExtra("q1result", 0);
// Find the View that shows the next TextView
TextView nextQuestion = (TextView) findViewById(R.id.next);
// Set a click listener on that View
nextQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
//Getting the answer to question 2 checkbox 1
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
//Calculate Question 2 score
int resultQ2 = calculateResultQ2(isCheckBox1Q2, isCheckBox2Q2, isCheckBox3Q2);
Intent question3Intent = new Intent(Question2Activity.this, Question3Activity.class);
question3Intent.putExtra ("q1result", resultQ1);
question3Intent.putExtra ("q2result", resultQ2);
startActivity(question3Intent);
}
});
// Find the View that shows the next TextView
TextView previousQuestion = (TextView) findViewById(R.id.previous);
// Set a click listener on that View
previousQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
Intent question1Intent = new Intent(Question2Activity.this, Question1Activity.class);
startActivity(question1Intent);
}
});
}
/**
* Check which checkbox was selected in the question 2
*
* @param checkBox1 is whether or not the user checked the checkbox1
* @param checkBox2 is whether or not the user checked the checkbox2
* @param checkBox3 is whether or not the user checked the checkbox3
* @return the score the user got for question 2
*/
private int calculateResultQ2(boolean checkBox1, boolean checkBox2, boolean checkBox3) {
int result = 0;
if (checkBox1 && checkBox2 && checkBox3) {
result = 1;
}
return result;
}
@Override
protected void onPause() {
super.onPause();
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
if(isCheckBox1Q2 == true){
mypref.edit().putBoolean("Iscb1Checked", true).apply();
}
else if(isCheckBox1Q2 == false){
mypref.edit().putBoolean("Iscb1Checked", false).apply();
}
if(isCheckBox2Q2 == true){
mypref.edit().putBoolean("Iscb2Checked", true).apply();
}
else if(isCheckBox2Q2 == false){
mypref.edit().putBoolean("Iscb2Checked", false).apply();
}
if(isCheckBox3Q2 == true){
mypref.edit().putBoolean("Iscb3Checked", true).apply();
}
else if(isCheckBox3Q2 == false){
mypref.edit().putBoolean("Iscb3Checked", false).apply();
}
}
@Override
protected void onResume() {
super.onResume();
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
if(mypref.contains("Iscb1Checked")){
if(mypref.getBoolean("Iscb1Checked",false)){
checkBox1Q2.setChecked(true);
}
}
if(mypref.contains("Iscb2Checked")){
if(mypref.getBoolean("Iscb2Checked",false)){
checkBox2Q2.setChecked(true);
}
}
if(mypref.contains("Iscb3Checked")){
if(mypref.getBoolean("Iscb3Checked",false)){
checkBox3Q2.setChecked(true);
}
}
}
}
请注意,我在 onPause() 中替换了以下内容;方法,因为我得到空异常:
checkBox1Q2.isChecked()
!checkBox1Q2.isChecked()
与
isCheckBox1Q2 == true
isCheckBox1Q2 == false
您可以使用 SharedPreference 来存储您的值。
1) 公开声明复选框和 SharedPreference:
CheckBox checkBox1Q2;
CheckBox checkBox2Q2;
CheckBox checkBox3Q2;
SharedPreferences mypref;
2) 在你的 onCreate() 中初始化 SharedPreference:
mypref = PreferenceManager.getDefaultSharedPreferences(this);
3) 在 onPause() 中保存复选框状态(因为按下后退按钮时会调用 onPause())。您也可以在 onStop() 或 onDestroy() 中声明。
@Override
protected void onPause() {
super.onPause();
if(checkBox1Q2.isChecked()){
mypref.edit().putBoolean("Iscb1Checked", true).apply();
}
else if(!checkBox1Q2.isChecked()){
mypref.edit().putBoolean("Iscb1Checked", false).apply();
}
if(checkBox2Q2.isChecked()){
mypref.edit().putBoolean("Iscb2Checked", true).apply();
}
else if(!checkBox2Q2.isChecked()){
mypref.edit().putBoolean("Iscb2Checked", false).apply();
}
if(checkBox3Q2.isChecked()){
mypref.edit().putBoolean("Iscb3Checked", true).apply();
}
else if(!checkBox3Q2.isChecked()){
mypref.edit().putBoolean("Iscb3Checked", false).apply();
}
}
4) 在 onResume() 方法中获取 CheckBox 状态:
@Override
protected void onResume() {
super.onResume();
if(mypref.contains("Iscb1Checked")){
if(mypref.getBoolean("Iscb1Checked",false)){
checkBox1Q2.setChecked(true);
}
}
if(mypref.contains("Iscb2Checked")){
if(mypref.getBoolean("Iscb2Checked",false)){
checkBox2Q2.setChecked(true);
}
}
if(mypref.contains("Iscb3Checked")){
if(mypref.getBoolean("Iscb3Checked",false)){
checkBox3Q2.setChecked(true);
}
}
}
您现在在 onClick 中获得复选框视图。尽量避免这种情况。始终在 onCreate 的初始部分(setContentView 之后)获取视图 (findViewById)。
我正在做一个多屏问答应用。对于每个问题,我都有一个单独的 activity / 屏幕。在每个屏幕的底部都有 next/previous "buttons" 导航到 next/previous 屏幕。请查看带有问题的屏幕 UI 示例:
不过我有一个问题。假设用户选择问题 2 的答案,然后单击 "Previous",选择问题 1 的答案并单击 "Next"。
我想保存问题 2 的 UI 状态,这样,如果用户通过单击上一个或下一个返回问题,所选答案将保留。
我设法完成的一件事是当用户单击 "previous" 时 UI 保持不变,我在清单文件中使用了以下代码:
android:launchMode="singleTask"
但是,当用户通过 "next" 提出问题时,我无法保存它。这是我的 activity 问题 2 的代码:
package com.example.justynagolawska.quizappiteration2;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
public class Question2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
ActionBar actionbar = getSupportActionBar();
// Applies the custom action bar style
getSupportActionBar().setDisplayOptions(actionbar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.action_bar);
// Changes the action bar title
TextView title = (TextView) getSupportActionBar().getCustomView().findViewById(R.id.action_bar_title);
title.setText(R.string.q2_name);
//Getting the intent with score for question 1
Intent question2Intent = getIntent();
final int resultQ1 = question2Intent.getIntExtra("q1result", 0);
// Find the View that shows the next TextView
TextView nextQuestion = (TextView) findViewById(R.id.next);
// Set a click listener on that View
nextQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
//Calculate Question 2 score
int resultQ2 = calculateResultQ2(isCheckBox1Q2, isCheckBox2Q2, isCheckBox3Q2);
Intent question3Intent = new Intent(Question2Activity.this, Question3Activity.class);
question3Intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
question3Intent.putExtra ("q1result", resultQ1);
question3Intent.putExtra ("q2result", resultQ2);
startActivity(question3Intent);
}
});
// Find the View that shows the next TextView
TextView previousQuestion = (TextView) findViewById(R.id.previous);
// Set a click listener on that View
previousQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
Intent question1Intent = new Intent(Question2Activity.this, Question1Activity.class);
startActivity(question1Intent);
}
});
}
/**
* Check which checkbox was selected in the question 2
*
* @param checkBox1 is whether or not the user checked the checkbox1
* @param checkBox2 is whether or not the user checked the checkbox2
* @param checkBox3 is whether or not the user checked the checkbox3
* @return the score the user got for question 2
*/
private int calculateResultQ2(boolean checkBox1, boolean checkBox2, boolean checkBox3) {
int result = 0;
if (checkBox1 && checkBox2 && checkBox3) {
result = 1;
}
return result;
}
如果有人能帮助我,我将不胜感激。谢谢!
编辑: 下面是我使用 sharedPreferences 的工作代码,@tahsinRupam
提出的解决方案package com.example.justynagolawska.quizappiteration2;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
public class Question2Activity extends AppCompatActivity {
SharedPreferences mypref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
final CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
final CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
final CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
mypref = PreferenceManager.getDefaultSharedPreferences(this);
ActionBar actionbar = getSupportActionBar();
// Applies the custom action bar style
getSupportActionBar().setDisplayOptions(actionbar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.action_bar);
// Changes the action bar title
TextView title = (TextView) getSupportActionBar().getCustomView().findViewById(R.id.action_bar_title);
title.setText(R.string.q2_name);
//Getting the intent with score for question 1
Intent question2Intent = getIntent();
final int resultQ1 = question2Intent.getIntExtra("q1result", 0);
// Find the View that shows the next TextView
TextView nextQuestion = (TextView) findViewById(R.id.next);
// Set a click listener on that View
nextQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
//Getting the answer to question 2 checkbox 1
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
//Calculate Question 2 score
int resultQ2 = calculateResultQ2(isCheckBox1Q2, isCheckBox2Q2, isCheckBox3Q2);
Intent question3Intent = new Intent(Question2Activity.this, Question3Activity.class);
question3Intent.putExtra ("q1result", resultQ1);
question3Intent.putExtra ("q2result", resultQ2);
startActivity(question3Intent);
}
});
// Find the View that shows the next TextView
TextView previousQuestion = (TextView) findViewById(R.id.previous);
// Set a click listener on that View
previousQuestion.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when next View is clicked on.
@Override
public void onClick(View view) {
Intent question1Intent = new Intent(Question2Activity.this, Question1Activity.class);
startActivity(question1Intent);
}
});
}
/**
* Check which checkbox was selected in the question 2
*
* @param checkBox1 is whether or not the user checked the checkbox1
* @param checkBox2 is whether or not the user checked the checkbox2
* @param checkBox3 is whether or not the user checked the checkbox3
* @return the score the user got for question 2
*/
private int calculateResultQ2(boolean checkBox1, boolean checkBox2, boolean checkBox3) {
int result = 0;
if (checkBox1 && checkBox2 && checkBox3) {
result = 1;
}
return result;
}
@Override
protected void onPause() {
super.onPause();
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
boolean isCheckBox1Q2 = checkBox1Q2.isChecked();
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
boolean isCheckBox2Q2 = checkBox2Q2.isChecked();
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
boolean isCheckBox3Q2 = checkBox3Q2.isChecked();
if(isCheckBox1Q2 == true){
mypref.edit().putBoolean("Iscb1Checked", true).apply();
}
else if(isCheckBox1Q2 == false){
mypref.edit().putBoolean("Iscb1Checked", false).apply();
}
if(isCheckBox2Q2 == true){
mypref.edit().putBoolean("Iscb2Checked", true).apply();
}
else if(isCheckBox2Q2 == false){
mypref.edit().putBoolean("Iscb2Checked", false).apply();
}
if(isCheckBox3Q2 == true){
mypref.edit().putBoolean("Iscb3Checked", true).apply();
}
else if(isCheckBox3Q2 == false){
mypref.edit().putBoolean("Iscb3Checked", false).apply();
}
}
@Override
protected void onResume() {
super.onResume();
//Getting the answer to question 2 checkbox 1
CheckBox checkBox1Q2 = (CheckBox) findViewById(R.id.checkbox1Q2);
//Getting the answer to question 2 checkbox 2
CheckBox checkBox2Q2 = (CheckBox) findViewById(R.id.checkbox2Q2);
//Getting the answer to question 2 checkbox 3
CheckBox checkBox3Q2 = (CheckBox) findViewById(R.id.checkbox3Q2);
if(mypref.contains("Iscb1Checked")){
if(mypref.getBoolean("Iscb1Checked",false)){
checkBox1Q2.setChecked(true);
}
}
if(mypref.contains("Iscb2Checked")){
if(mypref.getBoolean("Iscb2Checked",false)){
checkBox2Q2.setChecked(true);
}
}
if(mypref.contains("Iscb3Checked")){
if(mypref.getBoolean("Iscb3Checked",false)){
checkBox3Q2.setChecked(true);
}
}
}
}
请注意,我在 onPause() 中替换了以下内容;方法,因为我得到空异常:
checkBox1Q2.isChecked()
!checkBox1Q2.isChecked()
与
isCheckBox1Q2 == true
isCheckBox1Q2 == false
您可以使用 SharedPreference 来存储您的值。
1) 公开声明复选框和 SharedPreference:
CheckBox checkBox1Q2;
CheckBox checkBox2Q2;
CheckBox checkBox3Q2;
SharedPreferences mypref;
2) 在你的 onCreate() 中初始化 SharedPreference:
mypref = PreferenceManager.getDefaultSharedPreferences(this);
3) 在 onPause() 中保存复选框状态(因为按下后退按钮时会调用 onPause())。您也可以在 onStop() 或 onDestroy() 中声明。
@Override
protected void onPause() {
super.onPause();
if(checkBox1Q2.isChecked()){
mypref.edit().putBoolean("Iscb1Checked", true).apply();
}
else if(!checkBox1Q2.isChecked()){
mypref.edit().putBoolean("Iscb1Checked", false).apply();
}
if(checkBox2Q2.isChecked()){
mypref.edit().putBoolean("Iscb2Checked", true).apply();
}
else if(!checkBox2Q2.isChecked()){
mypref.edit().putBoolean("Iscb2Checked", false).apply();
}
if(checkBox3Q2.isChecked()){
mypref.edit().putBoolean("Iscb3Checked", true).apply();
}
else if(!checkBox3Q2.isChecked()){
mypref.edit().putBoolean("Iscb3Checked", false).apply();
}
}
4) 在 onResume() 方法中获取 CheckBox 状态:
@Override
protected void onResume() {
super.onResume();
if(mypref.contains("Iscb1Checked")){
if(mypref.getBoolean("Iscb1Checked",false)){
checkBox1Q2.setChecked(true);
}
}
if(mypref.contains("Iscb2Checked")){
if(mypref.getBoolean("Iscb2Checked",false)){
checkBox2Q2.setChecked(true);
}
}
if(mypref.contains("Iscb3Checked")){
if(mypref.getBoolean("Iscb3Checked",false)){
checkBox3Q2.setChecked(true);
}
}
}
您现在在 onClick 中获得复选框视图。尽量避免这种情况。始终在 onCreate 的初始部分(setContentView 之后)获取视图 (findViewById)。