Reputation: 409
I am working on Xamarin Forms and trying to port the application in both Android Tablet and Phone.
[Activity(Label = "SampleApp", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
App mainApp;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
mainApp = new App();
mainApp.ScreenWidth = (int)Resources.DisplayMetrics.WidthPixels;
mainApp.ScreenHeight = (int)Resources.DisplayMetrics.HeightPixels;
mainApp.LoadHomePage();
LoadApplication(mainApp);
}
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
mainApp.ScreenWidth = (int)Resources.DisplayMetrics.WidthPixels;
mainApp.ScreenHeight = (int)Resources.DisplayMetrics.HeightPixels;
mainApp.LoadHomePage();
}
}
From the above code, i am getting the width and height of the device display and also handling the Orientation change as well.
App.cs will load the HomePage and provides the screen width and height.
I am trying with Nexus 9 tablet and Nexus 6 mobile phone. The dimensions for nexus 9 are
I wanted to add 5 buttons horizontally in Stack layout. I want to set the width of the button relative to the device screen width.
int btnWidth = ScreenWidth / 5;
StackLayout headerPaneLayout = new StackLayout();
headerPaneLayout.Orientation = StackOrientation.Horizontal;
headerPaneLayout.BackgroundColor = Color.Yellow;
headerPaneLayout.Padding = new Thickness(0, 0, 0, 0);
mainLayout.Children.Add(headerPaneLayout);
Button btn1 = new Button();
btn1 .Text = "Take Survey";
btn1 .WidthRequest = btnWidth;
btn1 .HorizontalOptions = LayoutOptions.Start;
headerPaneLayout.Children.Add(btn1 );
Button btn2 = new Button();
btn2.Text = "PPE Product";
btn2.WidthRequest = btnWidth;
headerPaneLayout.Children.Add(btnPPEProduct);
I am getting the correct screen width and height for both phone and tablet.
But int btnWidth = ScreenWidth / 5;
is not working in my case.
int btnWidth = ScreenWidth / 10;
works for me.
If i use nexus 6 mobile i need to devide it by 18.
int btnWidth = ScreenWidth / 18;
I understand, i am making a logical mistake, but could not able to find the route cause.
Can any please suggest the best possible solution. I want to use to same UI and it should work for both tablets and mobiles. And also i want to arrive at logical dividing factor which is uniform.
Thanks in advance.
Upvotes: 0
Views: 111
Reputation: 409
Thanks for your help. I am missing the conversion from pixel to dp. I changed the MainActivity.cs code as below.
[Activity(Label = "SampleApp", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
App mainApp;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
mainApp = new App();
int screenWidth = (int)Resources.DisplayMetrics.WidthPixels;
int screenHeight = (int)Resources.DisplayMetrics.HeightPixels;
mainApp.ScreenWidth = ConvertPixelsToDp(Convert.ToSingle(screenWidth));
mainApp.ScreenHeight = ConvertPixelsToDp(Convert.ToSingle(screenHeight));
mainApp.LoadHomePage();
LoadApplication(mainApp);
}
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
int screenWidth = (int)Resources.DisplayMetrics.WidthPixels;
int screenHeight = (int)Resources.DisplayMetrics.HeightPixels;
mainApp.ScreenWidth = ConvertPixelsToDp(Convert.ToSingle(screenWidth));
mainApp.ScreenHeight = ConvertPixelsToDp(Convert.ToSingle(screenHeight));
mainApp.LoadHomePage();
}
}
private int ConvertPixelsToDp(float pixelValue)
{
var dp = (int)((pixelValue) / Resources.DisplayMetrics.Density);
return dp;
}
This works for me in all android devices with out any changes. And here is the link that helps me in resolving the issue. http://developer.xamarin.com/recipes/android/resources/device_specific/detect_screen_size/
Upvotes: 0
Reputation: 723
Button's WidthRequest is in device-independent units, while your ScreenWidth is in pixels. Use Resources.DisplayMetrics.Density to convert one to another.
Upvotes: 1
Reputation: 3266
You could try setting the StackLayout's HorizontalOptions to FillAndExpand and also set all the Buttons' HorizontalOptions to FillAndExpand and remove your explicit WidthRequests on the Buttons. This way all the Buttons would theoretically receive an equal portion of the screen's width.
If you want to continue down the path of setting explicit widths with respect to device width, it is important to note that there's a difference between pixels and density-independent units. This article has some helpful detail expanding on that topic, as well as sizing in Xamarin.Forms in general: https://download.xamarin.com/developer/xamarin-forms-book/BookPreview2-Ch05-Rel0203.pdf
Upvotes: 1