Сохранение/восстановление видимости для просмотра после изменения ориентации

У меня есть RelativeLayout с несколькими вложенными LinearLayouts. По умолчанию для LinearLayouts видимость отключена, поэтому ни один из них не виден при первой загрузке активности. У меня есть две кнопки, которые должны показывать/скрывать LinearLayouts при нажатии. Все отлично работает, за исключением случаев, когда устройство переориентировано, а атрибуты видимости сброшены на значение по умолчанию «ушло» в xml. Как сохранить текущее видимое состояние вида при изменении ориентации?

Изменить: окончательный код для всех, у кого есть проблема. По сути, просто добавьте видимый тег представления в SharedPreferences в пустоте, которая изменяет видимость, и проверьте его в 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();
    }

}

person jmease    schedule 15.02.2012    source источник
comment
Взгляните на эту тему: stackoverflow.com/questions/1410504/   -  person andrrs    schedule 16.02.2012
comment
См. также: stackoverflow.com/questions/8331129/   -  person jonp    schedule 16.02.2012
comment
@andrrs Спасибо, но я хочу, чтобы пользователь мог переориентировать экран. Я просто хочу, чтобы их выбор видимости остался с ними после переориентации.   -  person jmease    schedule 16.02.2012


Ответы (1)


Способ сделать это - поддерживать состояние представления в поле, если вам нужно поддерживать много настроек, вы, вероятно, захотите создать частный класс. тогда:

  1. переопределить метод onRetainNonConfigurationInstance и вернуть этот экземпляр.
  2. в методе onCreate извлеките экземпляр и, если он не нулевой, используйте его для восстановления этих значений. что-то вроде this.activityState = (UserAccountData) getLastNonConfigurationInstance();

Большинство людей не понимают, что активность воссоздается всякий раз, когда вы меняете ориентацию. Таким образом, это позволяет вам передавать эти настройки новому экземпляру.

person Joel Martinez    schedule 15.02.2012
comment
Спасибо. Возможно, вам придется немного приглушить это. ;) Итак, я переопределяю OnRetainNonConfigurationInstance в своем классе активности или создаю новый класс? Если последнее, то это тоже класс Activity? В моем OnCreate у этого нет ActivityState. Что такое моно эквивалент? На что ссылается UserAccountData, класс? - person jmease; 16.02.2012
comment
да, вы переопределяете это в своем классе активности. он позволяет платформе пользовательского интерфейса запрашивать у текущего экземпляра активности его состояние. вы правы, состояние активности не существует, пока вы его не добавите, обычно я создаю частный класс в своей деятельности, который имеет все свойства, которые мне нужно отслеживать. В этом примере (я должен был быть более явным, извиняюсь) UserAccountData было именем моего закрытого класса состояния. Точно такой же экземпляр, который вы возвращаете в OnRetainNonconfigurationInstance, будет возвращен в getLastNonConfigurationInstance(). - person Joel Martinez; 16.02.2012
comment
Пошли дальше и только что использовали ваше первое предложение для хранения его в поле или, точнее, в SharedPreferences. Для всех, у кого есть эта проблема, я обновлю свой код решением. Спасибо. - person jmease; 16.02.2012