Delpin Susai Raj Monday, 27 January 2020

Xamarin.Forms - Bottom TabbedPage in Android

In this blog post, you will learn how to Change Tabbed Page Top to Bottom for Android Device in Xamarin.Forms.

Introduction

Xamarin.Forms code runs on multiple platforms - each of which has its own filesystem. This means that reading and writing files is most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.


Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)
  • Xamarin.Forms 3.1 Later
The Problem

TabbedPage Native Behaviour

Android   - Top
iOS           - Bottom


MyTabbedPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:pages="clr-namespace:XMonkey.Views"
x:Class="XMonkey.Views.XMonkeyTabbedPage">
<!--Pages can be added as references or inline-->
<pages:BlogFeedPage Title="BlogFeedPage" IconImageSource="tab_feed.png"/>
<pages:AboutPage Title="AboutPage" IconImageSource="tab_about.png"/>
</TabbedPage>

Solution

Add android platform-specific code in TabbedPage

Namespace

xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
MyTabbedPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
xmlns:pages="clr-namespace:XMonkey.Views"
x:Class="XMonkey.Views.XMonkeyTabbedPage">
<!--Pages can be added as references or inline-->
<pages:BlogFeedPage Title="BlogFeedPage" IconImageSource="tab_feed.png"/>
<pages:AboutPage Title="AboutPage" IconImageSource="tab_about.png"/>
</TabbedPage>
Or C# Code Behind

MyTabbedPage.xaml.cs

using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
using Xamarin.Forms.Xaml;
namespace XMonkey.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class XMonkeyTabbedPage : Xamarin.Forms.TabbedPage
{
public XMonkeyTabbedPage()
{
InitializeComponent();
On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
}
}
Click the "Play" button to try it out.

Wow, It's Working.😍

I hope you have understood how to Change TabbedPage Top to Bottom for Android Device in Xamarin.Forms.

Thanks for reading. Please share your comments and feedback. Happy Coding 😀
Delpin Susai Raj Monday, 20 January 2020

Xamarin.Forms - Working with RefreshView

In this blog post, you will learn how to implement Pull to Refresh the Entire Page using RefreshView in Xamarin.Forms.


Introduction


Xamarin.Forms code runs on multiple platforms - each of which has its own filesystem. This means that reading and writing files are most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.

RefreshView (Pull to Refresh)

RefreshView is a container control that provides a pull to refresh functionality for scrollable content. Therefore, the child of a RefreshView must be a scrollable control, such as ScrollView, CollectionView, or ListView.

Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)
Setting up a Xamarin.Forms Project

Start by creating a new Xamarin.Forms project. You wíll learn more by going through the steps yourself.

Create a new or existing Xamarin forms(.Net standard) Project. With Android and iOS Platform.

Use RefreshView

Make sure your Controls should be within ScrollView.

<RefreshView IsRefreshing="{Binding IsRefreshing}" RefreshColor="Red"
Command="{Binding RefreshViewCommand}">
<ScrollView>
// your controls
</ScrollView>
</RefreshView>
view raw RefreshView.xml hosted with ❤ by GitHub
Setting up the User Interface

Here, Add RefreshView in your View. Make sure your content should be within ScrollView.

MainPage.Xaml

<?xml version="1.0" encoding="UTF-8"?>
<Pages:XMonkeyBasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:Behavior="clr-namespace:Prism.Behaviors;assembly=Prism.Forms"
xmlns:Pages="clr-namespace:XMonkey.Common.Pages"
xmlns:CustomViews="clr-namespace:XMonkey.Common.CustomViews"
x:Class="XMonkey.Views.BlogFeedPage">
<NavigationPage.TitleView>
<CustomViews:XMonkeyTitleView />
</NavigationPage.TitleView>
<Pages:XMonkeyBasePage.Behaviors>
<Behavior:EventToCommandBehavior EventName="Appearing" Command="{Binding RefreshCommand}"/>
<Behavior:EventToCommandBehavior EventName="Disappearing" Command="{Binding CleanUpCommand}"/>
</Pages:XMonkeyBasePage.Behaviors>
<Pages:XMonkeyBasePage.PageContent>
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshViewCommand}">
<ScrollView>
<FlexLayout Direction="Column" Margin="0,100,0,0"
AlignItems="Center">
<Label FontSize="Large" Text="{Binding Name}"/>
</FlexLayout>
</ScrollView>
</RefreshView>
</Pages:XMonkeyBasePage.PageContent>
</Pages:XMonkeyBasePage>
Add RefreshCommand 

Now, Add RefreshCommand for your RefreshView. This Command will perform while pull to refresh. After Refresh your data don't forget set IsRefreshing=false;

MainPageViewModel.cs

namespace XMonkey.ViewModels
{
public class BlogFeedPageViewModel:BaseViewModel
{
#region Fields
private string _name;
private bool _isRefreshing;
private Command _refreshViewCommand;
#endregion
#region Constructor
public BlogFeedPageViewModel()
{
}
#endregion
#region Properties
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
public bool IsRefreshing
{
get => _isRefreshing;
set => SetProperty(ref _isRefreshing, value);
}
public Command RefreshViewCommand
{
get
{
return _refreshViewCommand ?? (_refreshViewCommand = new Command(() =>
{
this.RefreshData();
}));
}
}
#endregion
#region Methods
private void RefreshData()
{
//Do your stuff
this.Name = "Delpin";
this.IsRefreshing = false;
}
#endregion
}
}
Click the "Play" button to try it out.

Change Refresh ActivityIndicator Color

Now, Change Refresh ActivityIndicator Color. Set RefreshColor="Color", Check bellow code.

MainPage.xaml

<RefreshView IsRefreshing="{Binding IsRefreshing}" RefreshColor="Red"
Command="{Binding RefreshViewCommand}">
<ScrollView>
<FlexLayout Direction="Column" Margin="0,100,0,0"
AlignItems="Center">
<Label FontSize="Large" Text="{Binding Name}"/>
</FlexLayout>
</ScrollView>
</RefreshView>
Click the "Play" button to try it out.

Wow, It's Working.😍

I hope you have understood how to use implement Pull to Refresh the Entire Page using RefreshView in Xamarin.Forms.

Thanks for reading. Please share your comments and feedback. Happy Coding 😀
Delpin Susai Raj Wednesday, 15 January 2020

Xamarin.Forms - Getting started with Prism

In this blog post, you will learn how to use Prism in existing Xamarin.Forms app.

Introduction

Xamarin.Forms code runs on multiple platforms - each of which has its own filesystem. This means that reading and writing files are most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.

MVVM

MVVM - Model View ViewModel
MVVM Is the design pattern to separate the user interface & business logic concerns. I suppose that you heard something about it. This pattern created by Microsoft is widely used with applications created with .NET Framework but not only because you can also use it with Xamarin.

Prism
Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Windows 10 UWP, and Xamarin Forms. Prism provides an implementation of a collection of design patterns that are helpful in writing well-structured and maintainable XAML applications, including MVVM, dependency injection, commands, EventAggregator, and others.

Prism Containers
  1. Unity
  2. DryIoc
Unity is the container I use and recommend the most. Unity is the most popular container due to it being the container that Brian has used for years and it is the first (and for a long time only) container available in the Templates. Unity is also about average with regards to its benchmark performance.

DryIoc is the container It's under active development, it's very fast, and works well with the current release of Prism. Also important is that when I have had questions or issues the maintainer has been very quick to address the issue or answer the question I had. It's for all of these reasons I continue to recommend the container.

Go with Prism Unity Container

Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)
Setting up a Xamarin.Forms Project

Start by creating a new Xamarin.Forms project. You wíll learn more by going through the steps yourself.

Create a new or existing Xamarin forms(.Net standard) Project. With Android and iOS Platform.

Install "Prism.Unity.Forms" Nuget

Now, add the following NuGet Packages.
  • Prism.Unity.Forms
Go to Solution Explorer and select your solution. Right-click and select "Manage NuGet Packages for Solution". Search "Prism.Unity.Forms" and add Package. Remember to install it for each project (.NET Standard, Android, iO, and UWP).

Change Application to PrismApplication

After install Prism.Unity.Prism, Change Application to PrismApplication in App.Xaml

App.xaml
<?xml version="1.0" encoding="utf-8"?>
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
x:Class="XMonkey.App">
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
view raw App.xaml hosted with ❤ by GitHub

Register NavigationService

Change Application to PrismApplication and add IPlatformInitializer to App Constructor.
Then register your content page and ViewModel using IContainerRegistry
  1. override OnInitialized (Initialize Components)
  2. override  RegisterTypes (Navigation Service Register)
Refer following code snippet.

App.xaml.cs
using Prism;
using Prism.Ioc;
using Prism.Unity;
public partial class App : PrismApplication
{
//public App()
//{
// InitializeComponent();
// //DependencyService.Register<MockDataStore>();
// Routing.RegisterRoute("aboutPage", typeof(AboutPage));
// Routing.RegisterRoute("itemsPage", typeof(ItemsPage));
// MainPage = new AppShell();
//}
#region Prism
public App(IPlatformInitializer platformInitializer = null) : base(platformInitializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync(PageConstants.MY_PAGE);
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<AboutPage, AboutPageViewModel>();
containerRegistry.RegisterForNavigation<MyPage, MyPageViewModel>();
}
#endregion
}
view raw App.xaml.cs hosted with ❤ by GitHub

Platform Setup

Android

Need to change IPlatformInitializer in LoadApplication.

MainActivity.cs
using Prism;
using Prism.Ioc;
namespace XMonkey.Droid
{
[Activity(Label = "XMonkey", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental", "CollectionView_Experimental", "FastRenderers_Experimental");
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
//Change LoadApplication IPlatformInitializer
LoadApplication(new App(new AndroidInitializer()));
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
view raw MainActivity.cs hosted with ❤ by GitHub

iOS

Need to change IPlatformInitializer in LoadApplication.

AppDelegate.cs
using Prism;
using Prism.Ioc;
using UIKit;
namespace XMonkey.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Xamarin.Calabash.Start();
global::Xamarin.Forms.Forms.Init();
//Change LoadApplication IPlatformInitializer
LoadApplication(new App(new iOSInitializer()));
return base.FinishedLaunching(app, options);
}
}
public class iOSInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
}
view raw AppDelegate.cs hosted with ❤ by GitHub

MVVM BindingContext

You no need to set BindingContext your ViewModel to ContentPage. Just create a ContentPage name ending with Page. (Ex: MyPage). Create a ViewModel name staring with ContentPage Name (ex: MyPageViewModel).

ViewModelLocator

If Viewmodel BindingContext is not working. Follow the below step.

ContentPage.xaml.cs
ViewModelLocator.SetAutowireViewModel(this,true);

ContentPage.Xaml
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"

Click the "Play" button to try it out.

Wow, it's working. 😍

I hope you have understood how to how to use Prism in existing Xamarin.Forms app.

Thanks for reading. Please share your comments and feedback. Happy Coding :)