2

I have a RelativeLayout with several nested LinearLayouts. By default the LinearLayouts have visiblity set to gone so none of them are visible when the activity first loads. I have two buttons that should show/hide LinearLayouts when pressed. Everything works great except when the device is reoriented and the visibility attributes are reset to the default "gone" in the xml. How do I retain the current visible state of a view during orientation change?

Edit: Final code for anyone else with the issue. Basically just add visible view tag to SharedPreferences in the void that changes visibility and check for it in OnCreate.

[Activity(Label = "My Activity", Theme="@style/TitleBar")]
public class CallManagement : Activity
{
    public LinearLayout parts; 
    public LinearLayout status; 

    ISharedPreferences p;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.CallManager);

        parts = (LinearLayout)FindViewById(Resource.Id.partLayout);
        status = (LinearLayout)FindViewById(Resource.Id.statLayout);

        p = PreferenceManager.GetDefaultSharedPreferences(this);
        var visible = p.GetString("VisibleLayout", null);

        if (visible != null && visible != "None")
        {
            RelativeLayout container = (RelativeLayout)FindViewById(Resource.Id.container);
            LinearLayout current = (LinearLayout)container.FindViewWithTag(visible);
            changeVisibility(current);
        }

        Button statusb = (Button)FindViewById(Resource.Id.changeStat);
        Button partsb = (Button)FindViewById(Resource.Id.addParts);

        statusb.Click += delegate
        {
            LinearLayout current = status;
            changeVisibility(current);
        };

        partsb.Click += delegate
        {
            LinearLayout current = parts;
            changeVisibility(current);
        };
    }

    void changeVisibility(View v)
    {           
        LinearLayout current = (LinearLayout)v;

        parts.Visibility = ViewStates.Gone;
        status.Visibility = ViewStates.Gone;

        var editor = p.Edit();

        if (v.Visibility == ViewStates.Gone)
        {
            v.Visibility = ViewStates.Visible;
            editor.PutString("VisibleLayout", v.Tag.ToString());
        }
        else
        {
            editor.PutString("VisibleLayout", "None");
        }

        editor.Commit();
    }

}
jmease
  • 2,507
  • 5
  • 49
  • 89
  • Take a look at this thread: http://stackoverflow.com/questions/1410504/how-to-make-application-completely-ignore-screen-orientation-change-in-android – andrrs Feb 15 '12 at 20:07
  • See also: http://stackoverflow.com/questions/8331129/screen-rotation-with-threading-using-mono-android/8331994#8331994 – jonp Feb 16 '12 at 03:21
  • @andrrs Thanks but I want the user to be able to reorient the screen. I just want their visibility choices to stick with them after reorientation. – jmease Feb 16 '12 at 16:30

1 Answers1

1

The way to do this is to maintain the view's state in a field, if you have a lot of settings to maintain, you probably want to make a private class. then:

  1. override the onRetainNonConfigurationInstance method and return that instance.
  2. in the onCreate method, retrieve the instance, and if it's not null, use it to reinstate those values. something like this.activityState = (UserAccountData) getLastNonConfigurationInstance();

Most people don't realize that the activity is recreated whenever you change orientation. So this lets you communicate these settings to the new instance.

Joel Martinez
  • 46,929
  • 26
  • 130
  • 185
  • Thanks. You might have to dumb this down just a little. ;) So I'm overriding OnRetainNonConfigurationInstance within my activity class or I'm creating a new class? If the latter, is it also an Activity class? In my OnCreate, this does not have activityState. What is the Mono equivalent? What is UserAccountData referencing, a class? – jmease Feb 16 '12 at 16:22
  • yes, you're overriding that in your activity class. it lets the UI framework ask your current activity instance for it's state. you are correct, "activitystate" isn't something that exists until you add it, I usually make a private class in my activity that has all the properties I need to track. In this example (I should have been more explicit, apologies), `UserAccountData` was the name of my private state class. The same exact instance that you return in OnRetainNonconfigurationInstance will be returned in getLastNonConfigurationInstance(). – Joel Martinez Feb 16 '12 at 16:57
  • Went ahead and just used your first suggestion for storing it in a field or more specifically SharedPreferences. For anyone else with this issue I will update my code with the solution. Thanks. – jmease Feb 16 '12 at 17:14