简体   繁体   English

防止xamarin,monodroid旋转后重新加载活动

[英]Prevent activity from reload after rotation in xamarin, monodroid

Ok... So my problem is to prevent from activity to reload after orientation is changed. 好的...所以我的问题是防止在方向改变后重新加载活动。 Basically, what I did is this: 基本上,我做的是这样的:

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

This is worked fine, until I changed "Target API" to 14. If I'm changing it back to 12, then everything is working, but on 14, activity is being restarted (OnCreate method is fires after rotation). 这很好,直到我将“Target API”更改为14.如果我将其更改回12,那么一切正常,但在14,活动正在重新启动(OnCreate方法在轮换后触发)。 So... You'll ask why do I need "Target API" 14? 那么......你会问为什么我需要“Target API”14? - Easy! - 简单! Because in my app, I'm playing video, and for that I need "true full screen". 因为在我的应用程序中,我正在播放视频,为此我需要“真正的全屏”。 All API's below 14 adding "Settings" (three dots) button. 所有API都在14以下添加“设置”(三个点)按钮。 In case of HTC, it's big and ugly button, that I was unable to get rid of. 在HTC的情况下,它是大而丑的按钮,我无法摆脱。

If you know how to do one of the two (Get rid of the "settings" button in API 12, or prevent activity from reload after orientation changed in API 14), I'll be very thank full for your help. 如果你知道如何做到这两个中的一个(去掉API 12中的“设置”按钮,或者在API 14中改变方向后防止重新加载活动),我将非常感谢你的帮助。

Ok... At last I solved it! 好的......最后我解决了! :) Saving activity state instead of preventing activity from reload, from first sight can seem to be a little tricky, but in fact is really easy and it's the best solution for situations like this. :)保存活动状态而不是阻止活动重新加载,从第一眼看起来似乎有点棘手,但实际上非常简单,这是这种情况的最佳解决方案。 In my case, I had a ListView, that populates from the internet with items, that stored in custom list adapter. 在我的例子中,我有一个ListView,它从互联网上填充了存储在自定义列表适配器中的项目。 If device orientation was changed, the activity was reloaded, so does the ListView, and I was loosing all the data. 如果更改了设备方向,则重新加载活动,ListView也是如此,我丢失了所有数据。 All I needed to do is to override the OnRetainNonConfigurationInstance method. 我需要做的就是覆盖OnRetainNonConfigurationInstance方法。 Here's a quick sample of how to do it. 这是一个如何做的快速示例。
First of all, we need a class, that can handle all of our stuff. 首先,我们需要一个可以处理所有内容的类。

Here is a wrapper for all the things we need to save: 这是我们需要保存的所有内容的包装器:

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

In our activity, we need to hold variables, to store all the data: 在我们的活动中,我们需要保存变量,以存储所有数据:

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

Then, we overriding the OnRetainNonConfigurationInstance method in the activity: 然后,我们覆盖活动中的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;
}

And the final stage is to load saved state in OnCreate method: 最后一步是在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
    }

}

And about the this._mListAdapter.CurrentPosition ... In my MainListAdapter , I added this property: 关于this._mListAdapter.CurrentPosition ...在我的MainListAdapter ,我添加了这个属性:

public int CurrentPosition { get; set; }

And the, in the `GetView' method, I did that: 并且,在`GetView'方法中,我做到了:

this.CurrentPosition = position - 2;

PS PS

You don't have to implement exactly as I showed here. 你不必像我在这里展示的那样完全实现。 In this code, I'm holding a lot of variables, and making all the routine inside the OnCreate method - that is wrong. 在这段代码中,我持有很多变量,并在OnCreate方法中制作所有例程 - 这是错误的。 I did that, just to show how it can be implemented. 我这样做,只是为了说明如何实现它。

what happen when orientation change (consider you enable rotation in your phone) ? 方向改变时会发生什么 (考虑在手机中启用旋转)?

Android restart activity onDestroy() is called, followed by onCreate() , you can distinguish between onDestroy() call to kill activity or restart app throw old answer . 调用Android重启活动onDestroy() ,然后调用onCreate() ,可以区分onDestroy()调用kill活动或重启app抛出旧答案

Prevent Activity restart 阻止活动重启

just set ConfigurationChanges to both Orientation , ScreenSize 只需将ConfigurationChanges设置OrientationScreenSize

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

why this may be not working ? 为什么这可能不起作用?

I dont think this will not working but set RetaintInstance to true read more about RetainInstance 我不认为这不会起作用,但将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;


        }

       .....

}

hope this help 希望这个帮助

Above API 13, you need to include screensize in your ConfigChanges. 在API 13之上,您需要在ConfigChanges中包含屏幕大小。

As denoted here. 如此处所示。

Maybe adding that tag to your activity for API13+ will help? 也许在API13 +的活动中添加该标签会有所帮助吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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