![](/img/trans.png)
[英]Xamarin.Forms dynamic layout depending on screen orientation or size
[英]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.