Creating Device-Specific Views in .NET MAUI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone dotnet mavi has made it ever so easier to build cross-platform applications for mobiles and desktop devices ranging from ios and android mobiles and tablets to windows and mac desktops and laptops but this also opens up a huge challenge for app ui design due to the screen real estate and orientation differences between the devices especially between phones versus tablets and desktops it becomes extremely difficult to create one app which can cater to both in most cases developers create two versions of the same app one targeting smaller devices such as mobiles or mobile phones and another for tablets and desktops so let us look at some examples here is the beautiful fantastical calendars app on app store mac app store and iphone this is one of the most acclaimed ui design on mac and iphone you can see over here the layout differences between the mobile and let's say a mac app or a tablet application it is not just the layout differences it is also the content which is different so imagine creating this ui as one application or one page in your same application let's look at another one this is your evernote's application again the same content the way information is presented is slightly different you have a site menu you have the list of all your notes and then the actual note which is open but on the mobile you have to go through the navigation for this this is your spotify application again usually different between the two and lastly this is apple's own music application so you get the idea the extra real estate and orientation on the desktops and tablets requires you to present more information on the screen which is otherwise not possible on the smaller mobile phones the screens on the bigger devices need to be reimagined rather than simply scaling up or changing the layout around of the content perhaps you know show even more content if needed because of the extra real estate in the uwp days we could use visual state manager and adaptive triggers to play around with the content layout and positioning defending depending on the device resolution but that is not possible with dotnet mavi in my uwp apps even i used adaptive triggers heavily but i still struggled with getting the ui and the layout design right across mobiles as well as desktops it was a huge struggle so let us come back to how we can solve this problem in dot net maui the very simplest way is to create separate views for different form factors and present the views accordingly but that actually opens up another issue which we will also talk about and resolve so let's let's go ahead and start with the blank project let me stop the slideshow here we go so this is a plain vanilla file new mavi application nothing fancy over here what we will do we will start with a simple landing page first so we will create two pages for this purpose one for mobile devices and another for desktops let us conveniently call these start pages as mobile start page and desktop start page and for easy maintenance going forward i will structure them in separate folders so first of all let us create subfolders for mobile and desktop and then we will create our pages there so what i would like to do i would create i would like to create a new folder i will like to call them views within views i will create two subfolders let's call them mobile and desktop and then i will create pages over here so under the desktop folder i will create a dotnet mavi content page and call it desktop start page and under the mobile i will create mobile start page and we will just change some text in both these pages to keep it simple something like welcome to mobile view in the mobile start page or welcome to desktop view in the desktop start page so this is our mobile start page let's say welcome to dotnet mavi from mobile application and we will go to our desktop page and we will say welcome to dotnet mavi on from desktop application now let us wire up these pages in the app startup file we will need to use conditional compilation for this let me show you the code if i go to my app starter so instead of this where we have main page equals to new uphill we will need to use conditional compilation so we'll say if android or ios we will do something else we will do something else so in android or ios we will say our main page equals to new navigation page and we'll say new mobile start page let me bring in the namespace and similarly for the desktop we will say it is desktop start page let me bring in this namespace as well and now let us run the app on both the mobile as well as desktops so i'm going to run it in the mobile simulator first i made a typo so here it is the app came up welcome to dotnet movie from mobile application and if i run the same application now on my mac or on a desktop we should see welcome to desktop application here you go welcome to dotnet mavi from desktop application so it works we now have different views across devices so basically problem solved correct well not exactly we have another problem now for this one page it is fine and very easy to do but as your application grows and you have more and more pages navigation becomes extremely difficult you have to apply the same kind of code and do conditional checks everywhere and every time you navigate to another page let me show you what i mean let us say that we now add a button to our start pages which will take us to our second page and assuming that the second page also needs to have different layouts depending on the devices that the app is running on we will need to create multiple views for it obviously so let's create these pages and just call them mobile second page and desktop second page i'm going to add mobile second page and i'm going to add desktop second page and for distinction purposes let's just change the text in these two pages to differentiate them so welcome to dotnet mavi welcome to second page of dot net movie from desktop and in the mobile second page welcome to second page of dot net mavi from mobile suite so let's now go back and wire up these pages from the start pages so what we can do we can add a button to the start pages and perform the navigation via the click event handlers so let me go to the start page and let's add a button over here let's call it text equals to navigate to second page and clicked some new event handler so here is our button for this page i can go and i can copy the same thing over here so now we have the buttons and now in the code behind let's do the navigation so i'll go to the button handlers and here i will say await navigation push async so we are in the mobile page new mobile second page and i can do the same from my desktop start page sorry yeah desktop start page here we go so let us now run the application and see if it works i'm running it in mac first so we have welcome to dotnet mavi from desktop application click the button takes us to the second page welcome to second page of dotnet mavi from mobile because i forgot to change it over here it should be desktop second page so let's run it again so we have the mac catalyst app running is the desktop start page desktop application navigate to second page welcome to second page of dot net money from desktop and if i run the same application on ios now i should be seeing the second page of the mobile so we have the mobile application navigate to second page and here we have the page which we created specifically for mobile so it works but we have hard coded navigation in the code behind based on mobile on the desktop pages no conditional compilation here but there is obviously duplication of code in the code behind and this was a very very simple page with just a button and navigation you may have a very complex layout with lot of visual elements and actions going on and anyways in majority of the cases you will be using mvvm pattern and bring in a view model to do all the heavy lifting for you and perform the navigation as well in fact i would anyway suggest that you use mvvm pattern with this approach so that you can eliminate the duplication of code in code behinds because we have multiple pages so let us change our application to use view models we will create a view model for our start page add a relay command to it and wire up the buttons in the pages to use this command first let me remove the click handlers so this was on the desktop start page mobile start page we can remove the same go back to the buttons we can remove them more buttons so we have removed the navigation from here and then we will need to create the view model let me quickly check if i did not make mistake anywhere that is fine so for the view models i'm going to create a new folder first calling it view models and i will create a view model called start page view model for simplicity sake i am going to just add a reference to i navigation service from the page in this view model and add it to my constructor and then we will hook up this view model in our pages so i can go to my desktop start page and there in the constructor i can say this dot binding context is equal to new start page view model passing in this navigation service let me bring in the namespace and i will do the same thing in my mobile start page by the way this is not the best way to connect views with the view models stay tuned and subscribe to this channel i will be posting another video making this process much easier by creating a base page and auto wiring up the view models so back to this we will now create a relay command in the relay command we will do the same thing that we did in the code behind and write code to navigate to device specific view but first we will make use of community toolkit dot mvvm package to make our life easier so let me go and add a package let me search for community toolkit dot mbvm if you have not used this package i highly recommend you look at this there are some beautiful things which are going around before this package you had to do or write all the boilerplate code yourself related to mbvm now anything to do with observable objects relay commands i notif i notify property change implementations everything is done for you automatically so let me go to my view model i will change the declaration to a partial class because we'll be using source generators to inject code and now i'm going to add a relay command so let me create a function let me call it navigate to [Music] second page and this this i can say await navigation service dot push async new let's say mobile second page let me bring in the namespaces for the community toolkit and for the file views okay so this is we are hard coding it to go to the mobile page but actually we need to do the same thing that we did in our app.xml file so let me just bring in the same code over here just to copy paste and i will replace it so if it is mobile views i will navigate to the mobile second page else i will navigate to the desktop second page next we will need to connect the buttons on the start pages to this new command that we have created and then we will run the application so let me go to my desktop start page so we remove the click handler now instead we will bring in a command binding navigate to second page and let me copy and paste the same in the mobile start page so here we go let us now run the application and see if nothing is broken so our simulator comes up navigate to second page and it is broken so finding navigation to second page command let's click on the circuit page it still does not work navigation is it let me go back navigate to second page command navigate to second page command navigate to second page command let's try it now yes it works as they say third time is the charm so it takes me to the second page of the mobile application if i run it on my mac it should do the same yeah here you go taking me to the second page from the desktop so basically it works but you get the issue let me go to the viewmodel even though it is working fine it is just too much of a hassle to do this if else business every time with the com conditional compilations and imagine if you want to have separate views for mobile separate views for tablets based on idioms and separate for desktops or even separate views between windows and mac or ios and android this will turn into a nightmare very soon so how can we fix this what if we could write a service to resolve the device specific views for us auto magically and i emphasize on auto magically it sounds very interesting right so let us actually do this for this we will create a new static class called view services and use that class to resolve the pages for us so let me create a new folder i am going to call it services and in this services i am going to create a static class called view services going to make it static and then i am going to add an extension method for our app builder i can remove the constructor so let me start up with i service collection so i can create private static i service collection let me call it services and then an extension method public static mavi app builder it returns above builder and let's call it use view services and we will pass in our builder in this what we will do we will just save the reference to the service collection from the builder application from the builder from the maui program into our services variable let's say builder dot services and then i'm going to just return this builder and we are done next i am going to create a simple helper method which is going to help us resolve content pages for us now it is too much code to write so i'm just going to cheat and do a copy paste but i will explain what i'm doing so it is a simple function that we have written it is called resolve pages it takes the type of the page and some input parameters that you want to pass when creating an instance of this page because in your constructor of your page it may be not take any parameter or it may be taking one two five ten different parameters or different types so what we are doing in this page we are finding out based on this service or the type of page that we have passed we are finding out what is the implementation for this page and then we are creating a let me and then we are creating a instance of this page and returning it back to our application so it is a very very simple implementation now with this done let us go back to our application and we need to use use this so all i can simply say is dot use view services let me bring in the namespace so we have wired it up in our mavi program next we need to create interfaces for each of our pages and register them in the di container then the view services will automatically or rather auto magically resolve the pages based on the device or idiom where the app is running on so let us create the interfaces i'm going to go and add a new folder and i'm going to call them iviews and here i'm going to create interfaces for my start page and second page so let me call it i start page it's a simple empty interface nothing needs to be done over here same i will do for i second page the next thing we will need to implement these interfaces in our pages so let me go back to our pages in the desktop second page i'm just going to go and implement the i second page let me bring in the namespace and i will do the same for my mobile second page i will implement the same interface and for the mobile start page i am going to implement i start page let me copy and i will do the same for my desktop start page so we have implemented our interfaces now the next thing we need to do we need to register these interfaces in our example we will be using conditional compilation to detect the operating system of the where the application is running on and register os specific pages accordingly so let me show you for this we can go to our mavi program now and let me just again save some time and copy paste the code so here again something i'm saying if conditional compilation check if it is android or ios add a single turn to the i istart page which is mobile start page i can change it to transient wherever needed and then i'm registering the second page on the mobile devices as mobile second page the same thing i'm doing on the desktop i'm registering the same interfaces but with different pages desktop start page and desktop second page now we are almost done all is that is left now is to go back to the places where we are navigating to the pages and use our view services helper method in instead so let us start with the app.xml and we do not need any of this we can get rid of this and we can simply now say main page equals to new navigation page and instead of passing in the specific page that we want we can say view services let me bring in dot resolve page so what is the page that we want over here we want the start page so that is all we need to do now if i run this application on the application start automatically for ios simulator it will show me the mobile view and in the mac catalyst it will show me the desktop view exactly the same thing i can do let me just copy paste or and go back to our view model as well i can also get rid of this whole thing and i can say await navigation service dot push async and this time i need to pass in i second page because i want the second page and let us run the application if all if all is working that is great now we have an error i think we forgot to add the desktop specific views by the way if i change it to mac catalyst it will show me these errors and then i can add them so let me read on the application again if everything is well the app should come up we have the welcome page from the desktop and if i click on navigate it will take me to the second page from desktop and if i run the same application on ios now the same thing should happen we have the welcome from the mobile application navigate to the second page and voila it works by the way you can also pass parameters to your construct to your to the constructors of your pages using this view services so let me show you an example of what i mean if i go to my second page and if i just create a constructor saying input data okay and let me also go ahead and add it to my desktop second page and i'm going to put a break point over here and then in our navigation service while i'm instantiating this second page i can just pass in some parameter this can be dynamically coming based on you are working on let's say it might be you you have a list of movies and when you click on a particular movie you want to navigate to the second page with that movie id so let me run it on mac quickly navigate to second page and you can see our breakpoint has been hit and the data has been passed from the view model when instantiating a new instance of this page so here you have it by the register reminder i will be posting a separate video on how to auto wire views with view models and pass such parameters directly to the view models so please stay tuned for that so yeah here you go an easy way to show mobile specific or device specific views in your applications i hope you found it useful stay tuned for more and press the like button and subscribe to the channel also click on the notification bell if you want to stay updated on the new content related to maui see you all
Info
Channel: Naweed Akram
Views: 13,894
Rating: undefined out of 5
Keywords: Maui, .Net Maui, #DotNetMaui, Dotnet Maui, Mobile Application Development, DotNet Maui Tutorial, .Net Maui Tutorial, .Net Maui App, Real-world Maui App, Device Specific Views, Mobile UI
Id: 7oVrdUELuYA
Channel Id: undefined
Length: 34min 51sec (2091 seconds)
Published: Wed Aug 17 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.