簡體   English   中英

在Xamarin.Forms中添加方向更改的布局

[英]Add a Layout on Orientation change in Xamarin.Forms

我需要實現的是,將畫面添加到現有頁面上將畫面從縱向更改為橫向。 我已設法使用void OnSizeAllocated(雙倍寬度,雙倍高度)檢測方向更改。 但是我不能在這個事件上添加布局。

我的樣本C#代碼是

   public class MyLayoutView : ContentPage
   {
      StackLayout portraitcontent = null;
      StackLayout landscapecontent = null;
      StackLayout footer = null;

   public MyLayoutView ()
    {

    portraitcontent = new StackLayout ();
    landscapecontent = new StackLayout ();
    footer = new StackLayout ();

    this.Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
    this.BackgroundColor = Color.FromHex ("#ffffff");
    this.Content = new StackLayout
        {
            Children =
            {
                portraitcontent ,
                landscapecontent ,
                footer 
            }
            };
         }
   }

OnSizeAllocated方法

   protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);

        if (width < height) {
            // In Portrait
            portraitcontent .IsVisible = true;
            landscapecontent.IsVisible = false;
            Debug.WriteLine ("Application Is in portrait");
        } else {
            // In Landscape
            portraitcontent .IsVisible = false;
            landscapecontent.IsVisible = true;

            landscapecontent.Children.Clear ();

            Label LandscapeLabel= new Label
            {
              Text = "<Each Time Text Changes>",
              HorizontalOptions = LayoutOptions.StartAndExpand,
              TextColor=Xamarin.Forms.Color.FromHex("#000000")
            };

            landscapecontent.Children.Add(LandscapeLabel); 

            Debug.WriteLine ("Application Is in Landscape");
        }
    }

當reenterancy被阻止時,它拋出無法修改集合的錯誤。 每次方向改變時,我都需要在stacklayout中添加一個新標簽。 我怎樣才能以適當的方式實現它?

提前致謝

覆蓋OnSizeAllocated可能不是最好的方法。 我只是把它放在我的代碼中,從縱向到橫向調用這個方法大約25次。

我正在嘗試的另一件事是在表單頁面上掛鈎事件處理程序:

this.SizeChanged += (sender, e) => setOrientation(this);    // Connect Orientation Switcher

為了跟蹤真正的頁面旋轉並避免處理器不必要的工作,我創建了一個類變量來存儲當前狀態,然后將其添加到高度/寬度比較中。

void setOrientation (Page p)
     if ( isPortrait && (p.Width > p.Height) ) { do stuff }
     if ( !isPortrait && (p.Width < p.Height) ) { do stuff }

這更快,但目前似乎存在內存泄漏,一些布局來回切換。 仍在努力。 不能相信移動設備已經有多年的屏幕輪換,開發工具可用,沒有簡單的方法來做到這一點。 似乎它們可以允許我們將幾個不同的布局連接到頁面,並讓運行時根據環境自動選擇。 我不是一個開發者,也許它比看起來應該對我來說要困難得多。

如果我得到輪換工作,我會盡量記得回來並發布代碼。

當方向更改時,調用已分配的大小多次。 我認為你必須做更多的驗證,例如檢查孩子的數量以避免重復觀看。

    if(landscapecontent.Children.Count>1)
     { 
       //Don't add any views
     }

只要我嘗試過就沒有旋轉的事件處理程序。 Itz有點破解代碼,以便在方向更改時更改視圖。

即使你可以在這里使用接受的答案..希望它符合你的目的..

對於Xamarin形式,PCL是檢測方向變化的錯誤層。 您需要使用特定於平台的代碼檢測它們,然后將其傳達給PCL。 對於我剛才正在進行的項目,這是我的解決方案:在PCL代碼中:

public interface IOrientation
    {
        AppOrientation CurrentOrientation { get; }
        IObservable<AppOrientation> Orientation { get; }
    }

    public enum AppOrientation
    {
        Unknown = 0,
        Portrait,
        Landscape
    }

在任何視圖(xaml頁面),關心我可以觀察方向更改:我使用autofac初始化ctor中的IOrientation,使用任何Ioc或服務分辨率最適合您。

public HomePage(IViewResolver resolver,IOrientation orientation)
{
    InitializeComponent();
     _resolver = resolver;
     this.SetContent();
     orientation.Orientation.ObserveOn(SynchronizationContext.Current)
     .Subscribe(x => this.SetContent());
}

對於Android:

在MainActivity.cs中,實現MainActivity的IOrientation。 public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity , IErrorReporting,IOrientation和ctor中的某個地方: _lastOrientation = this.Resources.Configuration.Orientation;

 #region IOrientation
        private Android.Content.Res.Orientation _lastOrientation;
        private readonly Subject<AppOrientation> _orientation = new Subject<AppOrientation>();

        public AppOrientation CurrentOrientation
        {
            get
            {
                return _lastOrientation == Android.Content.Res.Orientation.Portrait ? AppOrientation.Portrait :
                    _lastOrientation == Android.Content.Res.Orientation.Landscape ? AppOrientation.Landscape : 
                    AppOrientation.Unknown;
            }
        }
    public IObservable<AppOrientation> Orientation { get { return _orientation; } }

    public override void OnConfigurationChanged(Configuration newConfig)
    {
        base.OnConfigurationChanged(newConfig);
        if (newConfig.Orientation == this._lastOrientation)  return; 
        this._lastOrientation = newConfig.Orientation;

        this._orientation.OnNext(this.CurrentOrientation);

    }

    #endregion

在iOS中擴展Appdelegate public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate ,IOrientation和ctor中的某個地方: _lastOrientation = UIDevice.CurrentDevice.Orientation;

#region IOrientation

    private UIDeviceOrientation _lastOrientation = UIDeviceOrientation.Unknown;
    private readonly Subject<AppOrientation>  _orientation=new Subject<AppOrientation>();

    public AppOrientation CurrentOrientation
    {
        get
        {
            return
                (_lastOrientation == UIDeviceOrientation.LandscapeLeft || _lastOrientation == UIDeviceOrientation.LandscapeRight) ? AppOrientation.Landscape :
                (_lastOrientation == UIDeviceOrientation.Portrait || _lastOrientation == UIDeviceOrientation.PortraitUpsideDown) ? AppOrientation.Portrait : 
                AppOrientation.Unknown;
        }
    }

    public IObservable<AppOrientation> Orientation { get { return _orientation; } }

    #endregion

我沒有WP實現,但我不敢相信創建一個很難....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM