Android 如何在方向更改时使用 onSaveInstanceState 和 onRestoreInstanceState 保存状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10259776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:02:48  来源:igfitidea点击:

how to save state with onSaveInstanceState and onRestoreInstanceState while orientation change

androidandroid-orientation

提问by Reza Shek

I read almost all article about onSaveInstanceState and onRestoreInstanceState in Stack overflow but I cant solve my problem.
I have a text view and button in my main.java and while you click on button value of a ( ais an int variable) variable will increase and show in the text view, but, when I rotate my phone ( orientation change), text view reset.

我在堆栈溢出中阅读了几乎所有关于 onSaveInstanceState 和 onRestoreInstanceState 的文章,但我无法解决我的问题。
我的 main.java 中有一个文本视图和按钮,当您单击 a(a是一个 int 变量)的按钮值时,变量将增加并显示在文本视图中,但是,当我旋转手机(方向改变)时,文本视图重置。

I override onSaveInstanceState and onRestoreInstanceState but it doesn't work. one more thing, I have special layout-land.xml file for landscape view.

我覆盖了 onSaveInstanceState 和 onRestoreInstanceState 但它不起作用。还有一件事,我有特殊的 layout-land.xml 文件用于横向视图。

here is my code

这是我的代码

 import android.app.Activity; 
 import android.graphics.Typeface; 
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;

 public class main extends Activity {
     /** Called when the activity is first created. */   
   public int a = 0;     
   public String fonts="TAHOMA.TTF";

   TextView tv = (TextView) findViewById(R.id.salavat);      
   Button b = (Button) findViewById(R.id.showsalavat);

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       b.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View arg0) {
               a++;
               tv.setText(""+a);
            }
       });
   }
   @Override        
   protected void onSaveInstanceState(Bundle SavedInstanceState) {
      super.onSaveInstanceState(SavedInstanceState);            
      SavedInstanceState.putInt("salavat-count", a);
   }
   @Override    
   protected void onRestoreInstanceState(Bundle savedInstanceState) {
       super.onRestoreInstanceState(savedInstanceState);     
       a= savedInstanceState.getInt ("salavat-count");   
   } 
}

and here my main.xml

这里是我的 main.xml

    <TextView
        android:id="@+id/shoma"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/shoma"
        android:textSize="20sp" />

    <Button
        android:id="@+id/showsalavat"
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:text="+"
        android:textSize="100sp" />

    <TextView
        android:id="@+id/eltemas"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="55dp"
        android:text="@string/eltemas" />

    <TextView
        android:id="@+id/salavat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="35sp" />

    <TextView
        android:id="@+id/ferestade"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:text="@string/salavat"
        android:textSize="20sp" />

</LinearLayout>

    <TextView
        android:id="@+id/shoma"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/shoma"
        android:textSize="20sp" />

    <Button
        android:id="@+id/showsalavat"
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:text="+"
        android:textSize="100sp" />

    <TextView
        android:id="@+id/eltemas"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="55dp"
        android:text="@string/eltemas" />

    <TextView
        android:id="@+id/salavat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="35sp" />

    <TextView
        android:id="@+id/ferestade"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:text="@string/salavat"
        android:textSize="20sp" />

</LinearLayout>

I really need some help on this. I really appreciate your help.

我真的需要一些帮助。我真的很感谢你的帮助。

回答by Blundell

As an update, you could just set freezesText="true"

作为更新,您可以设置 freezesText="true"

http://developer.android.com/reference/android/R.attr.html#freezesText

http://developer.android.com/reference/android/R.attr.html#freezesText

 <TextView
    android:id="@+id/eltemas"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:freezesText="true"/>

Or

或者



This is the simplest example:

这是最简单的例子:

TextView yourTextView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    yourTextView = (TextView) findViewById(R.id.your_textview);

}

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString("YourTextViewTextIdentifier", yourTextView.getText().toString());

        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        yourTextView.setText(savedInstanceState.getString("YourTextViewTextIdentifier"));
    }

But having an inner class that represents your state will be much nicer when you start saving a lot of objects on orientation change.

但是,当您开始在方向更改时保存大量对象时,拥有一个代表您的状态的内部类会更好。

Using an inner class it would look like this below. You can imagine as you have more and more state to save the inner class makes it much easier (less messy) to handler.

使用内部类,它看起来像下面这样。你可以想象,当你有越来越多的状态来保存内部类时,它会更容易(不那么混乱)处理。

  private static class State implements Serializable {

    private static final String STATE = "com.your.package.classname.STATE";

    private String yourTextViewText;

    public State(String yourTextViewText) {
        this.yourTextViewText = yourTextViewText;
    }

    public String getYourTextViewText() {
        return yourTextViewText;
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    State s = new State(yourTextView.getText().toString());

    outState.putSerializable(State.STATE, s);

    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    State s = (State) savedInstanceState.getSerializable(State.STATE);

    yourTextView.setText(s.getYourTextViewText());
}

回答by Durgpal Singh

I think this code is helpful for you..

我认为这段代码对你有帮助..

public class MainActivity extends Activity 
{

    protected void onSaveInstanceState(Bundle outState) 
    {
        super.onSaveInstanceState(outState);
        System.out.println("TAG, onSavedInstanceState");

        final TextView text = (TextView)findViewById(R.id.textView1);
        CharSequence userText = text.getText();
        outState.putCharSequence("savedText", userText);
    }
    protected void onRestoreInstanceState(Bundle savedState) 
    {       
        System.out.println("TAG, onRestoreInstanceState");
        final TextView text = (TextView)findViewById(R.id.textView1);
        CharSequence userText = savedState.getCharSequence("savedText");
        text.setText(userText);
    }
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final String name = "5";

        final TextView show = (TextView)findViewById(R.id.textView1);
        Button btn = (Button)findViewById(R.id.button1);
        btn.setOnClickListener(new View.OnClickListener() 
        {

            public void onClick(View v) 
            {
                // TODO Auto-generated method stub

                show.setText(name);

            }
        });
    }
}

回答by DUDE_MXP

A neglected but serious mistake. You have to first pass the data to onSavedInstanceState() and the call onSavedInstanceState() . If you think then you will find that its useless to call onSavedInstanceState before passing the data to be saved. it wont save the activity instance as onSavedInstanceState ()is called before.. It should be as :

一个被忽视但严重的错误。您必须首先将数据传递给 onSavedInstanceState() 并调用 onSavedInstanceState() 。如果您认为那么您会发现在传递要保存的数据之前调用 onSavedInstanceState 是没有用的。它不会将活动实例保存为 onSavedInstanceState () 之前调用..它应该是:

@Override
protected void onSaveInstanceState(Bundle SavedInstanceState) 
{           
    SavedInstanceState.putInt("salavat-count", a);
    super.onSaveInstanceState(SavedInstanceState); 
}

回答by Nesim Razon

you need to reconstruct your view components with saved values. fill your textview with the saved value.

您需要使用保存的值重建您的视图组件。用保存的值填充你的文本视图。

@Override   
protected void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  a = savedInstanceState.getInt ("salavat-count");
  tv.setText(""+a);
}

回答by digulino

Do you really want to use these methods ?

你真的要使用这些方法吗?

Here you go a kind of solution to your problem, just put this inside your manifest file

在这里,您可以找到一种解决问题的方法,只需将其放入清单文件中

<activity android:name="package.subpackage.xptoactivity" android:configChanges="orientation"></activity>

If you do this, your Activity won't reload all the views reseting their values when you change the orientation

如果你这样做,当你改变方向时,你的 Activity 不会重新加载所有的视图来重置它们的值