简体   繁体   中英

How to restore state of an Android View (UI)?

I'm trying to save state of my view in one activity and pass it to another activity using a Bundle. In the second activity I try to restore the view state using the bundle.

First Activity

private View CreateView() {
ScrollView scrollView = new ScrollView(this);
final LinearLayout layout = new LinearLayout(this);
layout.setOrientation(android.widget.LinearLayout.VERTICAL);
scrollView.addView(layout);         
Button btn = new Button(this);
btn.setId(100);
btn.setText("Button Text");
btn.setOnClickListener(new ClickListener());
layout.addView(btn);
return scrollView;
}

onCreate

super.onCreate(savedInstanceState);
View v = CreateView();
setContentView(v);

Saving state

SparseArray<Parcelable> array = new SparseArray<Parcelable>();
view.saveHierarchyState(array);
Bundle bundle = new Bundle();
bundle.putSparseParcelableArray("state", array);
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtras(bundle);
startActivity(intent);

Second Activity onCreate

bundle = this.getIntent().getExtras();        
View view = new View(this);
view.restoreHierarchyState(bundle.getSparseParcelableArray("state"));
setContentView(view.getRootView());   
Button btn = (Button)findViewById(100);

Everything works without an exception. However, I face two issues: 1. The view in second activity is blank. Though I've restored the saved state I can't see anything 2. Instance for the button (with id 100) in second activity is always null

While debugging I can see one of the values in the bundle having an id 100

Any help on what I seem to be doing wrong will be appreciated. Thanks

I figured out that it is not possible to restore a view in a different activity from which it was initially created (or rendered). Since View is not a serializable type, it can't be send in its entirety as well. At this point there doesn't seem to be any solution (I haven't explored option of modifying Android source code)

Why are you trying to create a View programatically and sending it to another activity? You could simply use the same layout in both activities and then only pass the data that backs the view. That too there would be more convenient ways than using a parcelable?

Could you elaborate on what you are trying to achieve here? Maybe we can give you a better response then....

Have you tried doing this in onSavedInstanceState(...) ?

From the Android documentation:

onSaveInstanceState(Bundle) is called before placing the activity in such a background state, allowing you to save away any dynamic instance state in your activity into the given Bundle, to be later received in onCreate(Bundle)

The only approach I've taken with this is using the onSaveInstanceState and onRestoreInstanceState.

public void onSaveInstanceState(Bundle outState){
    //save the state of the sign up views!
    Serializable page0fields = sign_in_page.getFields();
    outState.putSerializable("page0fields", page0fields);
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
    //restore the state of the sign up views!
    sign_in_page.fillFields(
            savedInstanceState.getSerializable("page0fields")
            );
    super.onRestoreInstanceState(savedInstanceState);
}

On the other hand, you seem to desire a much more automated approach to this. I don't believe you can pass around views arbitrarily, as they aren't serializable, though I may be mistaken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM