Introduction
At this stage, you know the simple way to load an image from a URL. In this article, you are going to learn,
- Different ways to add images to your application.
- How to control Caching Up images downloaded from the internet.
- How to show an activity indicator while the image is downloading.
Targeted Audience
People with basic knowledge of C# and Xamarin.
Tools
Visual Studio with Xamarin Installed.
Image Sources
In Xamarin, we have two different types of images. We have images that are platform independent, like background images. Also, we have images that are specific to each platform, like icon and splash screens.
To include platform dependent images to our application, we have two options. We can download them using the URI (Unified Resource Identifier). Or, we can embed them in a Portable Class Library (PCL). If you want to work with icons for buttons, splash screens etc., you need to include different images in each application project.
Image Source Using URI
XAML
In the picture below, I have got an image element with a source set to its URI. “1920/1080” is the dimension of the image. “/sports” is the category and “/7” is the identifier for the image. So, you will always get the same image.
Code
- <?xml version="1.0" encoding="utf-8" ?>
- <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:local="clr-namespace:PracApp1"
- x:Class="PracApp1.MainPage"
- x:Name="ContentPage1">
- <Image Source="http://lorempixel.com/1920/1080/sports/7/"></Image>
- </ContentPage>
Code Behind
Create a new UriImageSource directly, set the URI, and store the result into the imageSource variable. The UriImageSource object has a couple of properties that you might be interested in. One of them is CachingEnable. It’s a Boolean and by default, it's true. When using XAML to add an image to your application, we set the image source to a Uri. The XAML parser internally creates a UriImageSource and as caching is enabled by default, that image is cached for the next 24 hours. Which means if you terminate your application and launch it again, that image is loaded from the cache.
But if sometimes, you want to disable caching, for example, you want to download a user’s profile image that can change. In those cases, you cannot use Xaml. Instead, we have to go to the code behind, directly create a UriImageSource object and set CachingEnabled to false. Another property is CacheValidity which is a TimeSpan object. You can set it to time for which you want to cache the image.
XAML Code
- <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:local="clr-namespace:PracApp1"
- x:Class="PracApp1.MainPage"
- x:Name="ContentPage1">
- <Image x:Name="image"></Image>
- </ContentPage>
C# Code
- public MainPage()
- {
- InitializeComponent();
-
- var imageSource = new UriImageSource { Uri = new Uri("http://lorempixel.com/1920/1080/sports/7/") };
- imageSource.CachingEnabled = false;
- imageSource.CacheValidity = TimeSpan.FromHours(1);
- image.Source = imageSource;
- }
Don’t forget there is an implicit conversion from the string to UriImageSource. So, if you set an image source through XAML, that string is converted to UriImageSource. This is the result if I run the code on iPhone 6s.
Image Aspect
You can see that the image is not fit according to the screen. But this image object has a property called “Aspect” which is an enumeration. You have three options in it - “AspectFill”, “AspectFit”, and “Fill”. You can set this property in XAML or code-behind.
Using C# Code
image.Aspect =Aspect.Fill;
Using XAML
<Image x:Name="image" Aspect="Fill"></Image>
You can see the image is distorted because we have got a landscape image that is stretched to fit into the dimensions of this device. The aspect we have is “AspectFill” which makes an image to fill the entire display area while preserving the aspect. So, you can see the image is not distorted; instead, it's cropped. This is useful to displaying background images.
Activity Indicator
While displaying images from the internet, it may take a few seconds until the image is loaded. In those cases, it’s better to display an Activity Indicator, which is like a loader icon in the middle of the screen.
You can use ActivityIndicator tag for this and set its height, width, and position. By default, I am doing my image to visible - false; so that you can see the activity indicator on the screen.
XAML CODE
- <AbsoluteLayout>
- <ActivityIndicator
- IsRunning="True"
- AbsoluteLayout.LayoutBounds="0.5, 0.5, 100, 100"
- AbsoluteLayout.LayoutFlags="PositionProportional">
- </ActivityIndicator>
- <Image IsVisible="False" x:Name="image" Aspect="Fill"></Image>
- </AbsoluteLayout>
As we want to show the activity indicator on the image load, we have to bind its running expression with the “IsLoading” property of the image. When the image is downloading from the internet, the IsLoading property will be true by default. And when it’s downloaded, it will be false. Now, I am removing the IsVisible tag from the image. Let’s see the results.
When the image was loading, the activity indicator appeared but when the image is loaded once, it disappeared.
XAML CODE
- <AbsoluteLayout>
- <ActivityIndicator
- IsRunning="{Binding Source={x:Reference image}, Path=IsLoading}}}"
- AbsoluteLayout.LayoutBounds="0.5, 0.5, 100, 100"
- AbsoluteLayout.LayoutFlags="PositionProportional">
- </ActivityIndicator>
- <Image x:Name="image" Aspect="Fill"
- AbsoluteLayout.LayoutBounds="0,0,1,1"
- AbsoluteLayout.LayoutFlags="All"></Image>
- </AbsoluteLayout>
Downloading an image is a way to add a platform independent image to your application. It's useful to build an app which uses a user’s gallery. Real world example of it is the Facebook App. You can browse different photos and as a photo is downloaded, the activity indicator appears.