【问题标题】:How to save activity state after navigating?导航后如何保存活动状态?
【发布时间】:2013-12-18 20:13:40
【问题描述】:

我有一个包含 3 个活动的应用程序,homecalculationResulthelp。当用户导航到 help 时,我要做的是在 calculationResult 上保存计算的详细信息。所以当用户在help中按下action bar后退图标时,计算的结果还是会在calculationResult中出现。

到目前为止,我已尝试通过遵循本指南来实现这一点:Recreating an activity,但是当我实现它时,与savedInstanceState一起使用时无法识别我想要存储的变量。以下是我尝试的方法在结果类中执行此操作。有人可以指出我在哪里出了问题,或者这是否是完成保存活动状态的正确方法?

public class CalcResult extends Activity implements OnClickListener{

TextView result1;

static final String MARK1 = "marking1";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.result);

        if (savedInstanceState != null) { 
            // Restore value of members from saved state 
            //not recognizing this variable mark1 which I'm setting to the variable that stores the result of the calculation.
            mark1 = savedInstanceState.getDouble(MARK1); 
        }

        final Intent intent1=new Intent(this,AboutActivity.class);
        final Intent intent2=new Intent(this,MainActivity.class);
        final Intent intent3=new Intent(this,MainActivity.class);

        final ViewGroup actionBarLayout = (ViewGroup) getLayoutInflater().inflate(
                R.layout.a,
                null);

        // Set up your ActionBar
        final ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setCustomView(actionBarLayout);

        final Button actionBarHome = (Button) findViewById(R.id.action_bar_title);
        actionBarHome.setBackgroundResource(R.drawable.ic_action_back);
        actionBarHome.setOnClickListener(this);
        actionBarHome.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {                

               startActivity(intent2);

            }

        });

        final Button actionBarInfo = (Button) findViewById(R.id.action_bar_staff);
        actionBarInfo.setBackgroundResource(R.drawable.ic_action_help);
        actionBarInfo.setOnClickListener(this);
        actionBarInfo.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {                

               startActivity(intent1);

            }

        });


        final Button actionBarHoome = (Button) findViewById(R.id.action_bar_home);
        actionBarHoome.setBackgroundResource(R.drawable.appicon);
        actionBarHoome.setOnClickListener(this);
        actionBarHoome.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {                

               startActivity(intent3);

            }

        });
        result1 = (TextView)findViewById(R.id.markOne);


        Intent intent = getIntent();

        double markOne = intent.getDoubleExtra("number1", 0);

        DecimalFormat df = new DecimalFormat("#.##");

        result1.setText(String.valueOf(df.format(markOne)+"mm"));

    }


    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save the user's current game state
        //Also doesn't recognise markOne here ->
        savedInstanceState.putDouble(MARK1, this.markOne);


        // Always call the superclass so it can save the view hierarchy state
        super.onSaveInstanceState(savedInstanceState);
    }

【问题讨论】:

  • markOne 不是该类的成员,而只是函数“onCreate”的成员,因此在任何其他函数中都不可见。而且您还必须覆盖“onRestoreInstanceState”

标签: android activity-lifecycle savestate


【解决方案1】:

而不是这个

double markOne = intent.getDoubleExtra("number1", 0);

你应该写

markOne = intent.getDoubleExtra("number1", 0);

通过再次声明它,您并没有将值分配给类级别markOne

您也可以尝试将 calculateResult 活动的 lauchmode 设置为 singleTop

 android:launchMode="singleTop"

这将使用已存在于堆栈顶部的同一活动实例,因此将具有与以前相同的状态。

当您移动到 ​​CalculationResult 活动时,尝试在您的 Help 活动中调用完成。

例如:

StartActivity(<Intent>);
finish();

【讨论】:

  • 感谢您的回复,我尝试将启动模式设置为singleTop,但这并没有解决问题。您知道如何保存它吗,我正在考虑将变量保存到内存中,你知道怎么做吗?
  • 当您移动到 ​​CalculationResult 活动时,尝试在您的 Help 活动中调用完成。
  • 那么,android:launchMode:finish 在帮助活动中?还是语法不同?
  • 启动calculationResult活动时的内部帮助活动只需调用finish()。
【解决方案2】:

onRestoreInstanceState() 在Activity 被操作系统杀死 时调用。 “这种情况发生在: • 设备方向改变(您的活动被销毁并重新创建) •您面前还有另一个活动,操作系统有时会终止您的活动以释放内存

下次您开始活动时,将调用 onRestoreInstanceState()。"

但在你的情况下,这可能不会发生。

【讨论】:

  • 你能给我看一个我的类的代码示例吗,这样比理论更容易理解。谢谢
  • 如何更简单的方法将值存储在共享首选项中并显示数据。默认情况下,您可以将值存储为“NOVALUE ENTERED”,如果该值被修改,您可以根据它更新 TextView。
【解决方案3】:

我遵循的方法

如果我第一次启动此活动,我会设置一个全局变量作为标志。如果全局变量与我设置的相同,我将保留 editText 不变。 (在你的情况下,结果1)。如果值改变,我设置这个值的editText。如果用户即使单击一次editText,我也会跟踪更改并存储该值。当您认为不再需要 mark1 时,您可以再次将 flag 的值设置为“FIRSTENTRY”。这会奏效。

如果您仍然遇到问题,请尝试告诉我们。

第 1 步

创建了一个类来存储静态全局变量。

public class Constants {        
public static String sFlag= "FIRSTENTRY";
}

第 2 步

在“setContentView(R.layout.result);”之后添加这段代码在您的 oncreate 方法中添加一行。 我将 result1 声明为 EditText,而不是 TextView。

if(!Constants.sFlag.equalsIgnoreCase("FIRSTENTRY"))
        {
            result1.setText(Constants.sFlag);
        }

        result1.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // TODO Auto-generated method stub
                Constants.sFlag = result1.getText().toString();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                Constants.sFlag = result1.getText().toString();

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                Constants.sFlag = result1.getText().toString();
            } 

        });

【讨论】:

    猜你喜欢
    • 2014-02-24
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-22
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    相关资源
    最近更新 更多