User interface programming overview (Android to Windows)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Learn about key similarities and differences between user interface programming models for Android and Windows Store apps.

Introduction

There are many similarities between Android and Windows Store apps to consider when designing and developing an app's UI. For example, an Activity is the unit of display in Android, and Page is the corresponding unit of display for Windows Store apps. This table compares corresponding UI elements in both Android and Windows 8.

This table gives more specific comparison info between Activity and Page objects.

Android apps Windows Store apps

An app is a collection of Activity objects.

An app is a collection of Page objects.

An Activity is the unit of display as seen by the end user.

A Page is the unit of display as seen by the end user.

Each Activity is designed to perform a function (such as sending an email message, taking a photo, or picking a contact).

Each Page object is designed to perform a function (such as sending an email message, taking a photo, or picking a contact). Each Page object is designed for the end user to interact with the app.

An Activity is a collection of layout controls and widgets (such as EditText, Button, and CheckBox).

A Page object is a collection of layout controls and widgets (such as TextBox, Button, and CheckBox).

Only one Activity can be seen by the end user at a time.

Only one Page can be seen by the end user at a time.

Activity objects are added to a last in, first out (LIFO) stack in the context of a Task. A back button click or the completion of an Activity will take it off of the stack and free it.

Page objects are added to a navigation stack within the app. There is no concept of a system-wide navigation stack. Data is shared between apps through contracts. Calling a contract (such as the Search contract) displays the target app. When the call is done, control goes back to the calling app. Within an app, users can navigate between pages with available navigation APIs.

 

To define, display, and run UI, both platforms use related sets of UI layout and run-time code files:

  • For each Activity in Android apps, the UI layout is in an .xml file, and the run-time code is in a .java file.
  • For each Page object in Windows Store apps:
    • For programming languages such as C++, C#, and Microsoft Visual Basic .NET, the UI layout is in a .xaml file. (A .xaml file is an XML-based file that follows the Extensible Application Markup Language (XAML) format.) The run-time code is in a .cpp, .cs, or .vb file.
    • For JavaScript, the UI layout is in a .html file, and the run-time code is in a .js file.

For Android apps, you use the observer pattern for event handling. Windows Store apps use Microsoft .NET delegates, which are similar to C function pointers but are simpler to program against. Both app platforms hide the complexity of binding handlers to widget events by enabling handlers to be declared in a .xml or .xaml file.

In both app platforms, you can develop composite UI that you can reuse across multiple units of display. Android app developers typically build compound components and fragments, while Windows Store app developers build UserControl objects.

Top

UI navigation

Android apps display activities and navigate between activities within the same app or between multiple apps. As the user navigates from one activity to another, activities are placed on a stack that can be navigated back and forth. This is typically done through a software or hardware "back" button typically located in the bottom task bar or through the in-app completion of the activity. Once an activity finishes its work, the activity is removed from the stack and the activity below the completed activity will come to the foreground. Android uses an explicit Intent to invoke activities within the same app, while an implicit Intent helps call activities in a different app or on the system.

Navigation within Windows Store apps is similar to the explicit Intent in Android apps. Windows Store apps display pages and navigate between pages within the same app through an app-specific navigation stack. There is no system-level page stack in Windows Store apps and provides no system-level "back button" to unwind a page stack.

This image shows how activity stacks and page stacks relate to Android and Windows Store apps navigation.

This code snippet shows activity navigation within an Android app through explicit intents.

public class Activity1 extends: Activity {
    // (Some code is omitted here for brevity.)
    void startActivity2() {
        Intent activity2 = new Intent(this, Activity2.class);
        startActivity(activity2);
    }
}

When this code is run, Android stops Activity1, adds Activity2 to the back stack, and displays Activity2. Activity1's UI context (including widget states) is preserved, but the activity is no longer in the foreground.

For Windows 8, navigation within an app happens through the Page object's Frame property that's set when the Frame object loads the Page object for display. The Frame object's Navigate method, as shown in this next code snippet, adds the new Page object to the navigation stack.

public partial class Page1: Page
{
    // (Some code is omitted here for brevity.)
    void StartPage2()
    {
        this.Frame.Navigate(typeof(Page2));
    }
}

The Frame object also provides GoBack and GoForward methods for navigating the relative page stack. The default behavior of the Navigate method is to create a brand new instance every time. However, this behavior can be overridden by caching pages by enabling the Page object's NavigationCacheMode property.

In Android apps, navigation between apps happens through an explicit Intent that is broadcast by Android to all the apps that can respond to it. In Windows Store apps, data sharing between apps is done through contracts and extensions. A contract is a well-defined interaction between two or more apps. An extension extends Windows 8 system features through a well-defined agreement. A contract is similar to an explicit Intent in Android.

Windows 8 contracts include:

  • File Open Picker
  • Search
  • Share

Extensions include:

  • Camera settings, which can display a custom UI when a certain manufacturer's camera is connected.
  • AutoPlay, which displays all the apps that declare this extension.
  • Print task settings where the app can display printer settings specific to a particular make and model when the printer is connected.

Similar to Android intent filters, contacts and extensions are specified in the Package.appxmanifest file of the corresponding Microsoft Visual Studio project. When the Share charm is tapped or sharing is started programmatically, Windows 8 lists all the apps that declared themselves as Share targets in their respective app manifests. The user then picks the app they want to share the data with. Windows Store apps declare their sharing behaviors by implementing the DataTransferManager class's DataRequested event handler. This handler is responsible for packaging the data that the Windows Runtime delivers to the Share target.

As an example, let's say that App1 implemented the DataRequested event handler to send data to App2, which declared itself as a Share target in its app manifest. This code snippet shows an implementation of the DataRequested event handler in App1.

public sealed partial class Page2 : Page
{
    public Page2()
    {
        this.InitializeComponent();
        RegisterForSharing();
    }

    private void RegisterForSharing()
    {
        DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
        dataTransferManager.DataRequested += new TypedEventHandler
                                                     <DataTransferManager, DataRequestedEventArgs>
                                                         (this.DataRequested);
    }

    private void DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
    {
        DataRequest request = e.Request;
        request.Data.Properties.Title = "Sharing text from App1";
        request.Data.Properties.Description = "Demo of Sharing contract";
        request.Data.SetText(textBox.Text);
    }
}

When the user selects App2 from the list of displayed share targets, Windows 8 calls the Application class's OnShareTargetActivated method. Each Windows Store app creates an App child class, that inherits from the Application class, for bootstrapping the app and displaying the app's first page. The Share target app overrides and provides a custom implementation for the OnShareTargetActivated method that extracts the data and passes control to the app's page. This next code snippet shows App2 activating Page3 after extracting the shared data that it received from App1.

sealed partial class App2 : Application
{
    // (Some code is omitted here for brevity.)
    protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
    {
        Page3 shareTargetPage = new Page3();
        shareTargetPage.Activate(args);
    }
}

// ...

public sealed partial class Page3 : Page
{
    ShareOperation _shareOperation;
    string _data;

    public Page3()
    {
        this.InitializeComponent();
    }

    public async void Activate(ShareTargetActivatedEventArgs args)
    {
        this._shareOperation = args.ShareOperation;
        this._data = await this._shareOperation.Data.GetTextAsync();
        Window.Current.Content = this;
        Window.Current.Activate();
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                this.tbShareResult.Text = this._data;
            }
        );
    }
}

After App2 is done processing the shared data, it can dismiss Page3 by calling the ShareOperation class's ReportCompleted method in any appropriate event handler that returns control back to Page2 of App1.

Top

Widget/control map

Both Android and Windows Store apps support similar widgets. These widgets include functionality for things such as text layout and display, text editing, lists, image display, radio buttons, and check boxes. They also include non-visual elements for content layout in vertical and horizontal stacks, grids, and other custom layout controls. This image shows a subset of the widget lists from both platforms.

Top

Event handling

Event handlers bind UI layout and run-time code files together into an app that works. Both Android and Windows Store apps provide similar event handlers with minor differences in how these handlers access widget state. Android projects in Eclipse enable handlers to be set within XML UI markup, as shown in this code snippet.

<!-- Only selected attributes are shown here. --!>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        tools:context=".MainActivity" >
    <TextView android:id="@+id/textView1" android:text="@string/hello_world" />
    <Button android:id="@+id/btnClickMe" android:onClick="btnClickMe_OnClick"/>
</RelativeLayout>

In Android, widget state changes can be handled in Java code by explicitly getting widget references through the Activity class's findViewById method, as shown in this code snippet.

public class MainActivity extends Activity {
    private TextView txtView;
    private Button btnClickMe;
    public void btnClickMe_onClick(View v) {
        txtView.setText(“The button was clicked!");
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnClickMe = (Button)findViewById(R.id.btnClickMe);
        txtView =(TextView)v.findViewById(R.id.txtView1);
    }

    // Other code not relevant to this discussion is removed for brevity.
}

In Windows Store apps, Visual Studio automatically generates widget references in the matching run-time code files so that event handlers and app logic can directly reference widgets, as shown in these code snippets.

<!-- Only selected attributes are shown here. --!>
<Page x:Class="ShareFrom.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="using:ShareFrom">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBox x:Name="tbShare" Text="Sharing Text" />
        <Button x:Name="btShare" Content="Share  Now" Click="btnClickMe_Click"/>
    </Grid>
</Page>
public sealed partial class MainPage : Page
{
    private void btnClickMe_Click(object sender, RoutedEventArgs e)
    {  
        textBlock.Text = "The button was clicked!";
    }

    // Other code not relevant to this discussion is removed for brevity.
}

Top

Screen layout

Similar to the Android screen designer in Eclipse, Microsoft Visual Studio 2013 has a built-in screen designer called Blend for Microsoft Visual Studio 2013. Blend enables widget layout in various ways, and is especially useful for advanced screen designs that require timeline-based animations, screen transitions, and complex color schemes and shapes.

Blend and Visual Studio 2013 share the same project format, so any changes to a project's files synchronize to both the tools.

This image shows a UI for a simple example data-entry app. The UI markup for both the Android and Windows Store app is similar, with a few differences.

  • Android Activity Java code depends on XML content while in Windows Store apps, the XAML code depends on runtime code in a supported programming language like C++, C#, Visual Basic .NET, or JavaScript.
  • Each widget in an Android app is identified by a unique integer, which is used to get a reference to the widget in runtime code. The name given to each widget follows a unique format which hints the code generator to place the generated integer literal in a particular static class. For example, the EditText object in the following code example has an id value of "@+id/name" that's used to create a new unique integer with name as the integer's name and creates it in a static class named id. In Android apps, this can be called with R.id.name to get references to the EditText object located in the object tree. This scheme by default requires that all the activities share the same widget namespace, which requires unique names for all of the widgets. By contrast, in Visual Studio, by default each page has a unique namespace, so widgets only have to be unique within each page.
<?xml version="1.0" encoding="utf-8"?>
<!-- Android apps -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp" >
    <EditText 
        android:id="@+id/name" android:layout_width="fill_parent"
        android:layout_height="wrap_content"        
        android:hint="@string/name" />
    <EditText
        android:id="@+id/address" android:layout_width="fill_parent"
        android:layout_height="wrap_content"        
        android:hint="@string/address" />
    <EditText
        android:id="@+id/company" android:layout_width="fill_parent"
        android:layout_height="wrap_content"        
        android:hint="@string/company" />
    <Button
        android:id="@+id/save" android:layout_width="100dp"
        android:layout_height="wrap_content"        
        android:text="@string/save" />
</LinearLayout>
<!-- Windows Store apps -->
<Page x:Class="Contoso.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Contoso"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Height="250" Width="281">

    <Grid Background="White">
        <TextBlock HorizontalAlignment="Center" Margin="0,35,0,0" Text="Contoso"
            VerticalAlignment="Top" Width="120" Height"27" Foreground="Black"
            FontSize="30" />
        <StackPanel Margin="0,80,0,0">
            <TextBox Name="tbName" TextWrapping="Wrap" Text="Enter Name"
                HorizontalAlignment="Center" Width="261" Foreground="#FFBBBDAF"/>
            <TextBox Name="tbAddress" TextWrapping="Wrap" Text="Enter Address"
                HorizontalAlignment="Center" Width="261" Foreground="#FFBBBDAF"/>
            <TextBox Name="tbCompany" TextWrapping="Wrap" Text="Enter Company"
                HorizontalAlignment="Center" Width="261" Foreground="#FFBBBDAF"/>
            <Button x:Name="btnSave" Content="Save" HorizontalAlignment="Center"
                Background="#FFDCE2DE" Foreground="#FF939587" Margin="0,0,122,0" />
        </StackPanel>
    </Grid>
</Page>

Top