【问题标题】:Prevent activity from reload after rotation in xamarin, monodroid防止在 xamarin、monodroid 中旋转后重新加载活动
【发布时间】:2013-08-11 16:43:14
【问题描述】:

好的...所以我的问题是防止活动在方向改变后重新加载。 基本上,我所做的是:

[Activity(Label = "migs", ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation)]

这很好,直到我将“目标 API”更改为 14。如果我将其更改回 12,则一切正常,但在 14 时,活动正在重新启动(OnCreate 方法在旋转后触发)。 所以......你会问我为什么需要“Target API”14? - 简单!因为在我的应用程序中,我正在播放视频,为此我需要“真正的全屏”。 14 以下的所有 API 添加“设置”(三个点)按钮。如果是 HTC,这是一个又大又丑的按钮,我无法摆脱。

如果您知道如何做到这两者之一(摆脱 API 12 中的“设置”按钮,或防止在 API 14 中更改方向后重新加载活动),我将非常感谢您的帮助。

【问题讨论】:

    标签: c# android android-activity xamarin.android xamarin


    【解决方案1】:

    好的...我终于解决了! :) 保存活动状态而不是阻止活动重新加载,乍一看似乎有点棘手,但实际上非常简单,它是此类情况的最佳解决方案。 就我而言,我有一个 ListView,它从 Internet 中填充项目,存储在自定义列表适配器中。如果更改了设备方向,则重新加载了活动,ListView 也是如此,并且我丢失了所有数据。 我需要做的就是重写OnRetainNonConfigurationInstance 方法。 这是一个如何做的快速示例。
    首先,我们需要一个可以处理我们所有东西的类。

    这是我们需要保存的所有内容的包装器:

    public class MainListAdapterWrapper : Java.Lang.Object
    {
        public Android.Widget.IListAdapter Adapter { get; set; }
        public int Position { get; set; }
        public List<YourObject> Items { get; set; }
    }
    

    在我们的活动中,我们需要保存变量,来存储所有数据:

    ListView _listView; //Our ListView
    List<YourObject> _yourObjectList; //Our items collection
    MainListAdapterWrapper _listBackup; //The instance of the saving state wrapper
    MainListAdapter _mListAdapter; //Adapter itself
    

    然后,我们在活动中重写OnRetainNonConfigurationInstance 方法:

    public override Java.Lang.Object OnRetainNonConfigurationInstance()
    {
        base.OnRetainNonConfigurationInstance();
        var adapterWrapper = new MainListAdapterWrapper();
        adapterWrapper.Position = this._mListAdapter.CurrentPosition; //I'll explain later from where this came from
        adapterWrapper.Adapter = this._listView.Adapter;
        adapterWrapper.Items = this._yourObjectList;
        return adapterWrapper;
    }
    

    最后阶段是在OnCreate方法中加载保存的状态:

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.list);
    
        this._listView = FindViewById<ListView>(Resource.Id.listView);
    
        if (LastNonConfigurationInstance != null)
        {
            this._listBackup = LastNonConfigurationInstance as MainListAdapterWrapper;
            this._yourObjectList = this._listBackup.Items;
            this._mListAdapter = this._listBackup.Adapter as MainListAdapter;
            this._listView.Adapter = this._mListAdapter;
    
            //Scrolling to the last position
            if(this._listBackup.Position > 0)
                this._listView.SetSelection(this._listBackup.Position);
        }
        else
        {
            this._listBackup = new MainListAdapterWrapper();
            //Here is the regular loading routine
        }
    
    }
    

    关于this._mListAdapter.CurrentPosition... 在我的MainListAdapter 中,我添加了这个属性:

    public int CurrentPosition { get; set; }
    

    在 `GetView' 方法中,我做到了:

    this.CurrentPosition = position - 2;
    

    附言

    您不必完全按照我在此处显示的那样实现。在这段代码中,我保存了很多变量,并在 OnCreate 方法中创建了所有例程 - 这是错误的。我这样做只是为了展示它是如何实现的。

    【讨论】:

      【解决方案2】:

      方向改变时会发生什么(假设您在手机中启用了旋转功能)?

      Android重启activityonDestroy()被调用,后面跟着onCreate(),你可以区分onDestroy()调用kill activity或者restart app throw old answer

      阻止 Activity 重启

      只需将 ConfigurationChanges 设置为 OrientationScreenSize

      [Activity (Label = "CodeLayoutActivity", ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
      

      为什么这可能不起作用?

      我不认为这不起作用,但将RetaintInstance 设置为 true 阅读更多关于 RetainInstance 的信息

      class myFragment: Fragment
          {
      
              public override void OnCreate(Bundle savedInstanceState)
              {
                  base.OnCreate(savedInstanceState);
                  this.RetainInstance = true;
                // this to change screen orientation 
                  Activity.RequestedOrientation = ScreenOrientation.Landscape;
      
      
              }
      
             .....
      
      }
      

      希望对你有所帮助

      【讨论】:

      • @MinaFawzy 只是一个简单的问题。我确实有两个活动,一个用于启动屏幕,另一个是 MainActivity,其余是片段,我应该在哪里维护 ConfigurationChanges 因为我已将启动屏幕活动设置为 MainLuncher true。谢谢。
      • 您可以将此行添加到应用程序中使用的所有活动中,您不必担心 MainLuncher 标志,您可以使某些活动(和其中的片段)不可旋转,而其他活动可旋转
      【解决方案3】:

      在 API 13 之上,您需要在 ConfigChanges 中包含 screensize。

      As denoted here.

      也许将该标签添加到您的 API13+ 活动中会有所帮助?

      【讨论】:

      • 不幸的是,这个解决方案不起作用,但感谢您的回答,我发现了为什么这不起作用。也许我应该尝试保存活动状态并重新加载它......我会尝试的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 2015-06-27
      • 1970-01-01
      相关资源
      最近更新 更多