如何在屏幕旋转时使用onSaveInstanceState和onRestoreInstanceState保存状态

3
我阅读了在Stack Overflow上关于onSaveInstanceState和onRestoreInstanceState的几乎所有文章,但我无法解决我的问题。我在主要的Java文件中有一个文本视图和一个按钮,当你点击按钮时a(a是一个int变量)变量的值会增加并显示在文本视图中,但是,当我旋转手机(改变方向)时,文本视图会重置。
我重写了onSaveInstanceState和onRestoreInstanceState但它不起作用。 还有一件事,我有一个专门用于横屏视图的layout-land.xml文件。
这是我的代码:
 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");   
   } 
}

这是我的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>

我非常需要在这个问题上得到帮助。非常感谢您的帮助。


3
真的吗?这可能是我见过的格式最差的代码了... - Alex Lockwood
@AlexLockwood 我知道我本来要“编辑”和整理一下,但后来我就想算了。 - Blundell
@Alexlockwood :嘿,你说得对。因为我是一个 Android 的新手。 - Reza Shek
这很有帮助 http://developer.android.com/training/basics/activity-lifecycle/recreating.html - Syed Raza Mehdi
这个回答解决了你的问题吗?当Android设备方向改变时保存Activity状态 - A P
似乎是 https://dev59.com/amcs5IYBdhLWcg3wPxce#61459807 的重复。 - A P
5个回答

7
作为更新,你可以设置freezesText="true" 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"/>

或者


这是最简单的例子:

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"));
    }

但是,如果你拥有一个代表你状态的内部类,在保存许多对象进行方向更改时会更好。

使用内部类后,代码如下所示。随着需要保存的状态越来越多,你可以想象内部类使得处理变得更加容易(不那么杂乱无章)。

  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());
}

5
我认为这段代码对你有帮助...
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);

            }
        });
    }
}

如果我们在更新TextView文本时有不同的文本颜色,那么我们如何保存它呢?你能帮我吗? - Gurjit Singh

0

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

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

0
一个被忽视但严重的错误。 你必须先将数据传递给onSavedInstanceState(),然后再调用onSavedInstanceState()。如果你仔细想一想,就会发现在传递要保存的数据之前调用onSavedInstanceState是没有意义的,因为它不会保存活动实例,因为onSavedInstanceState()是在之前被调用的。 正确的做法应该是:
@Override
protected void onSaveInstanceState(Bundle SavedInstanceState) 
{           
    SavedInstanceState.putInt("salavat-count", a);
    super.onSaveInstanceState(SavedInstanceState); 
}

-1

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

这里有一种解决方案可以解决你的问题,只需将其放入你的清单文件中即可。

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

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

4
这不是一个解决方案,而是解决屏幕方向切换问题的一种权宜之计。你的应用在多种情况下可能会重新启动,而屏幕方向变化只是其中之一。 - srgtuszy
广泛公开建议避免这种做法,因为随着Android的发展,它已经不再是一种解决方法。 - Omaraf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接