[Proposal] OnScreenSize Markup
See original GitHub issueOnScreenSize Markup
- Proposed
- Prototype: Repo and nuget
- Implementation: Works for Xamarin, I will port to Maui.
- iOS Support
- Android Support
- macOS Support
- Windows Support
- Unit Tests: Not Started
- Sample: Not Started
- Documentation: Needs improvements
Link to Discussion
Please link to the completed/approved Discussion
Summary
OnScreenSize Markup: A Markup for controlling Views according to a category a screen size fits in (Small, Medium, Large, ExtraLarge, etc).
Detailed Design
ScreenCategories.cs enum:
Depending on the screen-size (Width/Heigh), or a device model is, a ScreenCategories
enum is used.
public enum ScreenCategories
{
ExtraSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
ExtraLarge = 5,
NotSet = 6,
}
}
ICategoryFallbackHandler.cs:
This interface is used to determine the category a device fits in, during first execution we attempt to execute TryGetCategoryByDeviceModel
and wether it returns false, we attempt to execute TryGetCategoryByPhysicalSize
public interface ICategoryFallbackHandler
{
bool TryGetCategoryByDeviceModel(string deviceModel, out ScreenCategories category);
bool TryGetCategoryByPhysicalSize(double deviceWidth, double deviceHeight, out ScreenCategories category);
}
OnScreenSize.cs:
The markup itself.
- During the first run, the methods
ICategoryFallbackHandler.TryGetCategoryByDeviceModel
andICategoryFallbackHandler.TryGetCategoryByPhysicalSize
are called to determine theDevice Category
a device fits in, and after that, its result is cached to optimize next runs. - Depending on the
Device Category
a device was categorized, a value will be obtained from it’s corresponding Markup’s property. For instance: If device category was categorized aLarge
, the markup will attempt to get the value from propertyOnScreenSize.Large
. - In case a markup property is not defined, it will attempt to use the value from the
OnScreenSize.DefaultSize
.
Note: Before returning, each markup property’s value are attempted to be converted to its property-type, making it possible to have a batter user experience, but allowing values to be converted to GridLength
, Colors
, Thinkness
, RowDefinition
, ColumnDefinition
, and etc.
public class OnScreenSize : IMarkupExtension
{
public OnScreenSize();
public object DefaultSize { get; set; }
public object ExtraSmall {get;set;}
public object Small {get;set;}
public object Medium {get;set;}
public object Large {get;set;}
public object ExtraLarge {get;set;}
public object ProvideValue(IServiceProvider serviceProvider);
}
Usage Syntax
XAML Usage
<Label
Padding="{markups:OnScreenSize
Medium='15, 15, 0, 0',
Large='20, 20, 0, 0',
DefaultSize='10, 10, 0, 0'}"
Text="{Binding Location.Name}" TextColor="White" />
<ContentPage.Resources>
<Style x:Key="MainGridStyle" TargetType="Grid">
<Setter Property="RowDefinitions">
<markups:OnScreenSize>
<markups:OnScreenSize.Small>0.25*, 0.13*, 0.08*, 230, *</markups:OnScreenSize.Small>
<markups:OnScreenSize.Large>0.15*, 0.1*, 0.01*, 290, *</markups:OnScreenSize.Large>
<markups:OnScreenSize.DefaultSize>0.15*, 0.1*, 0.01*, 290, *</markups:OnScreenSize.DefaultSize>
</markups:OnScreenSize>
</Setter>
<Setter Property="ColumnDefinitions">
<markups:OnScreenSize>
<markups:OnScreenSize.Small>*, 230, *</markups:OnScreenSize.Small>
<markups:OnScreenSize.Large>*, 290, *</markups:OnScreenSize.Large>
<markups:OnScreenSize.DefaultSize>*, 290, *</markups:OnScreenSize.DefaultSize>
</markups:OnScreenSize>
</Setter>
</Style>
</ContentPage.Resources>
<Grid RowSpacing="0" Padding="0" Style="{StaticResource MainGridStyle}">
...
</Grid>
C# Usage
There is no code-equivalent for instantiating a Markup, since IServiceProvider
instance from OnScreenSize.ProvideValue(IServiceProvider serviceProvider)
is only available via XAML.
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:21 (9 by maintainers)
Top GitHub Comments
Just to say that this would be a fantastic addition - In the real world we have to support multiple device sizes - This is a real pain!!! We usually test on iPhone SE 1st generation vs the iPhone max pro and similar for android, this would solve so much crappy code we had to write to handle both in a very clean fashion If does not cover .all scenarios you can think of, that is absolutely fine , its something that can evolve -otherwise it will never see the light of day, If it supports ios-Android only at the beginning it would be a fantastic start.
This should really be embedded in Maui but that will never happen in the short time.
Confused if this is approved already or not… Cant wait to try it out.
Sorry I do also intend on responding on the bits of our discussion but I haven’t found time to properly read through it and come up with a response yet. Hopefully in the next few days I will