How to create simple animation in your Windows Phone app

Creating animations in your Windows Phone application is easier than you think.

I created a simple application that shows how to create a static animation and a dynamic animation. Both animations fill the following red rectangle from the bottom to the top.

image

Static animation

An animation uses a Storyboard object. It is usually created in the XAML file, because it is easier this way. Here is the XAML code:

<phone:PhoneApplicationPage x:Class="SimpleAnimationApp.StaticAnimationPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone">

    <phone:PhoneApplicationPage.Resources>

        <Storyboard x:Name="staticAnimation">

            <DoubleAnimation Duration="0:0:5"
                             To="700"
                             Storyboard.TargetProperty="Height"
                             Storyboard.TargetName="rectangleRed" />

        </Storyboard>

    </phone:PhoneApplicationPage.Resources>
    
    <Grid>

    <Rectangle Fill="Blue"
               Height="700"
               Width="100"
               VerticalAlignment="Bottom"/>

    <Rectangle Fill="Red"
               Height="0"
               Width="100"
               VerticalAlignment="Bottom"
               x:Name="rectangleRed"/>

    </Grid>

</phone:PhoneApplicationPage>

The DoubleAnimation is the simplest animation available, it animates a property that uses a double value. The above double animation is defined like this: Animate the Height property of the rectangleRed object from the current Height value to 700 in 5 seconds.

To start the animation, you need to call the Begin method on the animation:

using System.Windows.Navigation;

namespace SimpleAnimationApp
{
    public partial class StaticAnimationPage
    {
        public StaticAnimationPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            staticAnimation.Begin();
        }
    }
}

It is not used in the sample app, but if you want to stop an animation at any time, you just have to call the Stop method on the animation.


Dynamic animation

For the dynamic animation, let’s pretend that the properties Duration and To are specified in the code behind. We have the similar XAML code:

<phone:PhoneApplicationPage x:Class="SimpleAnimationApp.DynamicAnimationPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone">

    <phone:PhoneApplicationPage.Resources>

        <Storyboard x:Name="dynamicAnimation">

            <DoubleAnimation Storyboard.TargetProperty="Height"
                             Storyboard.TargetName="rectangleRed"
                             x:Name="doubleAnimation" />

        </Storyboard>

    </phone:PhoneApplicationPage.Resources>
    
    <Grid>

    <Rectangle Fill="Blue"
               Height="700"
               Width="100"
               VerticalAlignment="Bottom"/>

    <Rectangle Fill="Red"
               Height="0"
               Width="100"
               VerticalAlignment="Bottom"
               x:Name="rectangleRed"/>

    </Grid>

</phone:PhoneApplicationPage>

There is one addition of the x:Name=”doubleAnimation” which will help to control the animation in the code behind:

using System;
using System.Windows.Navigation;

namespace SimpleAnimationApp
{
    public partial class DynamicAnimationPage
    {
        public DynamicAnimationPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            doubleAnimation.Duration = new TimeSpan(0, 0, 0, 10);
            doubleAnimation.To = 350;

            dynamicAnimation.Begin();
        }
    }
}

Before starting the animation, I set the Duration to 5 seconds and the To to 350 which is half the size of the blue rectangle.

It is not complicated to create an animation. Those were simple animations, but if you want to create more complex animations and even combine animations, you can find more information on the web.

Put some life in your control!

Download Sample project

Windows Phone 8 SDK new features for developers

I dug in the Windows Phone 8 object browser and I found some interesting classes:

Microsoft.Phone.Controls.WebBrowserExtensions

In WP7, there is only the GetCookies method.
In WP8, there are the new ClearCookiesAsync and ClearInternetCacheAsync methods.

Windows.Phone.Networking.NetworkOperators.SmsInterceptor

There is a event called SmsReceived which could be really interesting to use. However, there is a little note saying: “This API is not intended to be used directly from your code”.

Windows.UI.Input.EdgeGesture, Windows.Devices.Input.MouseCapabilities and Windows.Devices.Input.KeyboardCapabilities

They all seem interesting, but I was not able to instantiate them. I get this exception: Requested Windows Runtime type ‘Windows.Devices.Input.MouseCapabilities’ is not registered.

Windows.ApplicationModel.Store

This namespace contains a lot of cool classes:

  • LicenseInformation (ExpirationDate, IsActive, IsTrial, ProductLicences).
  • ListingInformation (AgeRating, CurrentMarket, Description, FormattedPrice, Name, ProductListings)
  • ProductLicense (ExpirationDate, IsActive, IsConsumable, ProductId)
  • ProductListing (Description, FormattedPrice, ImageUri, Keywords, Name, ProductId, ProductType, Tag)
  • CurrentApp (GetAppReceiptAsync, LoadListingInformationAsync, LoadListingInformationByKeywordsAsync, RequestProductPurchageAsync)

I hope these classes will be available to use in applications. They could be useful in making marketplace apps!

Windows.System.Launcher

The Launcher class has LaunchFileAsync and LaunchUriAsync. The summary of LaunchUriAsync is: Starts the default app associated with the specified file or protocol.

I tried it with the protocol mailto:email@company.com and it launched the mail application! It will be cool if applications can register file type. Please note that I did not see a way to do that.

There are a lot more, but because I’m not sure if they will be available in the release version, it will better to wait for the final bits of the SDK.

Windows Phone 8 shared core with Windows 8 – File IO

For developers, the biggest news for Windows Phone 8 is that it shares a core with Windows 8. It means that your code has more chances than ever before to be compatible on both platforms.

One of the easier components and surely the most used in applications is the File IO component. In this post, I’ll also cover the Windows Phone 7 code compatibility.

In Windows Phone 7

To write a file, you use the IsolatedStorageFile:

private void WriteFile(string fileName, string content)
{
    using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream isolatedStorageFileStream = isolatedStorageFile.CreateFile(fileName))
        {
            using (StreamWriter streamWriter = new StreamWriter(isolatedStorageFileStream))
            {
                streamWriter.Write(content);
            }
        }
    }
}

To read a file:

private string ReadFile(string fileName)
{
    string text;

    using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream isolatedStorageFileStream = isolatedStorageFile.OpenFile(fileName, FileMode.Open))
        {
            using (StreamReader streamReader = new StreamReader(isolatedStorageFileStream))
            {
                text = streamReader.ReadToEnd();
            }
        }
    }

    return text;
}

In Windows Phone 8

To write a file, you use the Windows.Storage component. The file and folder objects are respectively IStorageFile and IStorageFolder. The usage of the await and async keywords come in.

To write a file:

public async Task WriteFile(string fileName, string text)
{
    IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;

    IStorageFile storageFile = await applicationFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

    using (Stream stream = await storageFile.OpenStreamForWriteAsync())
    {
        byte[] content = Encoding.UTF8.GetBytes(text);
        await stream.WriteAsync(content, 0, content.Length);
    }
}

To read a file:

public async Task<string> ReadFile(string fileName)
{
    string text;
    IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;

    IStorageFile storageFile = await applicationFolder.GetFileAsync(fileName);

    IRandomAccessStream accessStream = await storageFile.OpenReadAsync();

    using (Stream stream = accessStream.AsStreamForRead((int)accessStream.Size))
    {
        byte[] content = new byte[stream.Length];
        await stream.ReadAsync(content, 0, (int) stream.Length);

        text = Encoding.UTF8.GetString(content, 0, content.Length);
    }

    return text;
}

You can use these methods this way:

await WriteFile("Dummy.txt", "I love the Windows Phone");
string text = await ReadFile("Dummy.txt");

You can see that the code between Windows Phone 7 and Windows Phone 8 is quite different.

Compatibility

As we know already, Microsoft announced that the Windows Phone 7 applications will run on Windows Phone 8. This is great news. What is even better is that your Windows Phone 7 code that uses the IsolatedStorage will compile without any changes in Windows Phone 8. You can take the Windows Phone 7 code above and it will work.

You might be wondering if the internal folder structure is different between WP7 and WP8… The difference is minor.

In WP7, if you create a file at the root, the file will point to:

C:DataUsersDefaultAppAccountAppData{9679D8C4-24B4-41DF-85C5-5E099947F109}LocalIsolatedStoreDummy.txt

In WP8, the same file created at the root will be in:

C:DataUsersDefaultAppAccountAppData{9679D8C4-24B4-41DF-85C5-5E099947F109}LocalDummy.txt

The difference is the IsolatedStore folder added in WP7. It means that if you have old WP7 code that you would like to use with new WP8 code, you just have to get the IsolatedStore folder:

IStorageFolder applicationFolder = 
    await ApplicationData.Current.LocalFolder.GetFolderAsync("IsolatedStore");

In the end, you can mix both WP7 and WP8 code in your next Windows Phone 8 application. However, I would encourage you to use only the Windows Phone 8 version, as it will then be easier for you to use the same code in Windows 8.

Windows Phone 8 Battery API

The Battery API makes a nice addition to the WP8 SDK.

I can see in the near future that some applications will display the battery metrics on a Live Tile or in the application that hides the System Tray.

The Battery API is pretty easy to use:
1- Get the Battery instance with Battery.GetDefault().
2- Bind to the event RemainingChargePercentChanged.

The battery properties are:
RemainingChargePercent: gets a value that indicates the percentage of the charge remaining on the phone’s battery.
RemainingDischargeTime: gets a value that estimates how much time is left until the phone’s battery is fully discharged. 

With the following code:

using Windows.Phone.Devices.Power;

namespace BatteryApp
{
    public partial class MainPage
    {
        private readonly Battery _battery;

        public MainPage()
        {
            InitializeComponent();

            _battery = Battery.GetDefault();

            _battery.RemainingChargePercentChanged += OnRemainingChargePercentChanged;

            UpdateUI();
        }

        private void OnRemainingChargePercentChanged(object sender, object e)
        {
            UpdateUI();
        }

        private void UpdateUI()
        {
            textBlockRemainingCharge.Text = string.Format("{0} %", _battery.RemainingChargePercent);
            textBlockDischargeTime.Text = string.Format("{0} minutes", _battery.RemainingDischargeTime.TotalMinutes);
        }
    }
}

You get:

image


Please note that when running this on the emulator, it will show 100% and an infinite discharge time. The above values are fake.

Get ready to code!