Introduction
Most mobile apps need an internet connection to work properly and you, as the developer, are responsible for responding to changes of the connection status. For example, you need to inform users that the connection dropped, and depending on the scenario, you might also need to offer different actions. You probably already know that handling changes in the status of the network connection is accomplished via the Xamarin.Essentials.Connectivity class, but in this article, I will show how to implement a Snackbar view to inform the user. This view does not exist in Xamarin.Forms, but it has become very popular in many applications because it does not block the user interaction while providing information. Actually, the Xamarin Community Toolkit library includes Snackbar views, but not fully custom and nice looking as you learn here. For a better understanding, consider the following figure where you see the final result of the work.
As you can see, the user interface displays a nice view that informs the user that the connection dropped, while the other views have been programmatically disabled. Such a view will disappear once the connection is established again, and the other views will be re-enabled. Let’s now go through each step required to build this component.
Building a Snackbar view
A Snackbar can basically be thought of as a box that appears as an overlay to provide information to the user. This can include errors, confirmations, warning messages, and so on. The benefit of using a Snackbar is that it does not block the user interaction with the app, and you have complete control of it. For instance, you could animate a Snackbar to make it appear, keep the information visible for a few seconds, and then make it disappear. A typical situation for this is when the user saves some changes and the app provides a confirmation. In the case of the lost network connection, it could be a good idea to keep the Snackbar visible until the connection returns. Obviously, depending on the design requirements, you will change the behavior accordingly.
The implementation of the Snackbar can be done in a separate ContentView object. The following listing shows the full code for the Snackbar you see in the previous figure, and the new control is called NoNetworkSnackBarView.
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CrossPlatformCapabilities.NoNetworkSnackBarView">
<ContentView.Content>
<Grid>
<Frame
BackgroundColor="PaleVioletRed"
BorderColor="Red"
CornerRadius="10"
VerticalOptions="End"
HasShadow="False"
Padding="16">
<StackLayout
Orientation="Horizontal"
Spacing="16"
Margin="0"
Padding="0">
<Image
Source="ExclamationMark.png"
HorizontalOptions="Start"
HeightRequest="20"
WidthRequest="20"
VerticalOptions="CenterAndExpand" />
<StackLayout
Margin="10,0,0,0"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
Orientation="Vertical"
Spacing="5">
<Label TextColor="White"
FontSize="Medium"
Text="Internet connection unavailable..."
HorizontalTextAlignment="Center"/>
<ActivityIndicator
IsRunning="True" Color="White"
VerticalOptions="Center"
HeightRequest="35"
WidthRequest="35"/>
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</ContentView.Content>
</ContentView>
You can even go a step further and build a completely reusable Snackbar by binding the Label's properties, such as Text and TextColor, and the Frame color properties to objects in a view model. This is actually how I have my Snackbar views, which also need to be localized. For the sake of simplicity, and because we just need a specific message, in this article you see a Snackbar that is tailored for loss of connectivity.
The code is very simple, as it combines StackLayout panels to organize an icon, a text message, and a running ActivityIndicator inside a Frame.
Handling the status of the network connection
The Connectivity class exposes an event called ConnectivityChanged, which is raised every time the status of the network connection changes. Because you might have multiple pages in your app that require a connection, the best place to handle the event is in the App class. First of all, add the following line right after the invocation to the InitializeComponent method, inside the constructor:
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
The event handler might look like the following:
private void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e) {
MessagingCenter.Send(this, "ConnectionEvent", e.NetworkAccess == NetworkAccess.Internet);
}
You can further manage the event using the values from the NetworkAccess enumeration if you need more granularity of control. There is actually an additional thing to do: the network check will not happen immediately at startup, so you need to handle the OnStart method as follows:
protected override void OnStart() {
MessagingCenter.Send(this, "ConnectionEvent", Connectivity.NetworkAccess == NetworkAccess.Internet);
}
The same check is done at startup, just once, and the same message is sent to the subscribers. The next step is notifying the app’s user interface of the network status change and showing the Snackbar.
Because the event is handled in the App class, and this does not have direct access to the user interface of any page, the best way to inform all the subscribers that the network status changed is sending a broadcast message via the MessagingCenter class and its Send method. The message includes a bool parameter, which is true if an internet connection is available, otherwise false, whether the device is completely disconnected from any network or connected to a local network or to a network with limited access.
Notifying the user interface and showing the Snackbar
All the pages that will want to display the Snackbar when the connection drops off will need to subscribe the ConnectionEvent message via the MessagingCenter.Subscribe method. In the current example there is only one page, so the following snippet shows the code for the MainPage.xaml.cs file:
public partial class MainPage: ContentPage {
public MainPage() {
InitializeComponent();
MessagingCenter.Subscribe < App, bool > (this, "ConnectionEvent", ManageConnection);
}
private void ManageConnection(App arg1, bool arg2) {
LayoutRoot.IsEnabled = arg2;
ConnectionStatusBar.IsVisible = !arg2;
}
}
The page subscribes for the message sent by the App class and expects a bool value, which in this case is true if the connection is available and of type Internet, and otherwise false. When the message is raised, the ManageConnection method is invoked. LayoutRoot is a Grid that I added to the layout that Visual Studio autogenerated when creating the solution, and ConnectionStatusBar is the instance name for the NoNetworkSnackBarView control. The following listing shows the full XAML markup for the MainPage.xaml file:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:local="clr-namespace:CrossPlatformCapabilities" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="CrossPlatformCapabilities.MainPage">
<Grid x:Name="LayoutRoot">
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
</Frame>
<Label Text="Start developing now" FontSize="Title" Padding="30,10,30,10"/>
<!-- Text cut for spacing reasons, look in Visual Studio -->
<Label Text="Make changes to your XAML file and save..." FontSize="16" Padding="30,0,30,0"/>
<Label FontSize="16" Padding="30,24,30,0">
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="Learn more at "/>
<Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/>
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
<local:NoNetworkSnackBarView x:Name="ConnectionStatusBar"/>
</Grid>
</ContentPage>
If you now run the app and disable the internet connection on your device, you will see the Snackbar appear like in the previous figure. When you re-enable the connection, the Snackbar will disappear. Handling changes in the network connection is probably the most common task with mobile app development, but here you have seen a step further, which is related to a nice user interface, rather than focusing on the information only.