Nic Wise: The best design is no design at all: AppleWatch Edition

No, not THAT AppleWatch Edition. From Supertop, makers of Unread

One Less Thing.
We spent a lot of time not making a Watch app. We love our new wrist computers but they are not the place for reading articles.

This. 100 times this. So many of the watch apps I’ve seen – and Today Extensions – should never have been written. Just because you CAN write a Watch extension, doesn’t mean you should, especially if all it does is launch your phone app (ahem Evernote).

Out of my three remaining apps:

  • Nearest Bus is a prime candidate for a watch app. That’s next on my list.
  • Trip Wallet should never have one. Ever. No reason at all.
  • MobileAgent could – starting a timer or mileage maybe, but otherwise, no. If there was a way to get realtime, pushed bank account info that might be somewhat useful, but really, it’s just a notification.

And of the ones I work in at the day job (not that I have much say in which ones would get it):

  • goMoney – balances and transfers maybe, but as there is no push of information to the phone (and hence watch), it’s not overly useful (IMO – the company might think otherwise). It’s just a notification in the end (and how often do you do a transfer?)

So think carefullly about if a Watch app – or a Today Extension for that matter – even makes sense1 before you commit to making one.


  1. It might be that it doesn’t make UX/technical sense, but it has marketing value. Thats fine, I guess…. ¯_(?)_/¯ ?

Johan Karlsson: San Francisco

It’s a beautiful Monday morning in San Francisco today! Started the day with a morning run along the piers and ended up in the hotel lobby drinking cheap coffee while working on my new cool Xamarin Forms control.

The control is a simple to use, no hassle carousel view for images that works out of the box by simply setting a list. It also comes with a framework to lazy load images on demand while keeping the memory at a minimal.

Is it done, nope not yet! But it will be available at github real soon. And perhaps I’ll add it to Xamarin Forms Labs though I’m not to fund of their choice of OS license.

Michael Ridland: WWDC 2015 for a Xamarin Developer n+1 Series

How much can happen in a week? … well a lot, last week I was honoured to be announced as a Xamarin MVP, I purchased my first Apple Watch and… I’ve been lucky enough to win a golden ticket for the Apple World Wide Developers conference (WWDC). When I say win I mean pay apple $1999 […]

The post WWDC 2015 for a Xamarin Developer n+1 Series appeared first on Michael Ridland.

XHackers Team: CocosSharp Beginner Series : Setup your Machine

CocosSharp, as explained in my earlier post is a cross-platform library for building 2D games. CocosSharp is an open source library and is built on top of the MonoGame engine and the fine work from the Cocos2D, Cocos2D-x and Cocos2D-XNA communities.

Today, we will start our CocosSharp beginner series with an introduction on How to set up your machine for getting started with CocosSharp.

First of all, you can either use Xamarin studio or Visual studio as an IDE for your game development. The only difference is Xamarin studio can be installed on Windows and Mac. But visual studio can’t be directly installed on a Mac, you need virtualization tools like parallels or VMWare etc. on top of which you should run windows OS.

So, zero on your IDE and install the same.

Using Xamarin Studio

Xamarin Studio

Once you have xamarin studio installed, navigate to Add-in Manager
CS-2

As it’s already installed on my machine, you see a blue check mark on the top with Disable and Uninstall buttons on the right. If you have picked a fresh machine, with Xamarin Studio just installed, Click and install “CocosSharp Project Templates”. Once installed successfully, click on the first tab (Installed) and you should see CocosSharp there.
Android CocosSharp Project on Windows

On a machine running windows with Xamarin Studio installed, You will see only Android CocosSharp project types.

  • CocosSharp showcase has boilerplate code with all required packages pre-installed to get started.
  • CocosSharp empty game is a template to start your game from scratch.

On a Mac

For installing CocosSharp project templates, follow the steps mentioned above. Once installed successfully, specifically within the list of C# solutions you should now have CocosSharp projects for

  • Android
  • iOS/Classic API/iPad or iPhone or Universal
  • Mac/Classic API
  • Mobile Apps

provided you have all the necessary dependencies.

Xamarin Studio on a Mac Xamarin Studio on a Mac

Using Visual Studio

The templates are being held in a custom Visual Studio Gallery held at Mobile Essentials.

In order to get the custom gallery into your Visual Studio, open Tools | Options and configure the page Environment > Extension Manager as follows, using the gallery url http://gallery.mobileessentials.org/feed.atom:

image

Once the Mobile Essential gallery is set up, you can go to Visual Studio’s Tools | Extensions and Updates… menu and a new Mobile Essentials node will appear under the Online category, where you can explore and install the tools:

CS-05This image has been resized to fit in the page. Click to enlarge.


Click the Download button to install the highlighted extension.

Once the download is complete you will get a verification screen prompting you to install the template package.

Click the Install button:

image

Once installation is complete you will then see the CocosSharp Templates package marked with a little green arrow showing that it is installed.

image

This image has been resized to fit in the page. Click to enlarge.

Creating a new project

Now when creating a new project you will see a new section called CocosSharp with subcategories for:

  • Android
  • iOS
  • Windows

image

If you have created an empty CocosSharp project, right-click on From Packages | Add packages and then select platform specific CocosSharp Nuget package to get started. After successful installation, your project hierarchy should look like the one showed below. Showcase project template will look like this by default as packages will be pre-installed.

Project hierarchy with packages

Note : Check for updates before installing/updating latest packages.

Huff!!! hope everything went well with the machine setup for you. If you can’t wait for the next chapter in our beginner series, Start exploring and share your experience via twitter @IAmVMac
Game ON !!!!

Adam Kemp: Taming The Android Activity, Part 1

The Activity is a core building block in an Android application, but in some cases it can be a pain to work with. This article is part one of a series showing how to deal with some of the complexities of the Activity in a clean way using some of the capabilities of C# available to Xamarin.Android developers.

Typically each screen in an Android application is represented by an Activity, and moving from one screen to another is done by starting a new Activity. In fact, the Activity and its related class Intent are the keys to Android’s ability to let applications reuse pieces of other applications. That cross-application use case was the motivation behind the design of the Activity, but that design has the unfortunate side effect of making some common in-process use cases surprisingly difficult to deal with.

This series will cover three common scenarios that Android developers face in which the design of the Activity class causes problems:

  1. Dealing with device rotation (and other configuration changes)
  2. Launching and waiting for the results of another Activity
  3. Communicating between (in-process) Activitys

Each of these is very common and yet is surprisingly difficult to do on Android, especially compared to the way that view controllers work in iOS.

Configuration Changes

The Android documentation has this to say about configuration changes (emphasis added):

If the configuration of the device (as defined by the Resources.Configuration class) changes, then anything displaying a user interface will need to update to match that configuration. Because Activity is the primary mechanism for interacting with the user, it includes special support for handling configuration changes.

Unless you specify otherwise, a configuration change (such as a change in screen orientation, language, input devices, etc) will cause your current activity to be destroyed, going through the normal activity lifecycle process of onPause(), onStop(), and onDestroy() as appropriate.

What this means is that any “configuration change” will cause your Activity object to be destroyed and then recreated. What’s a “configuration change”? There are actually a lot of things that count (see the complete list), but one of the most common is an orientation change. As a result, if a user rotates his device from portrait to landscape (or vice versa) then your Activity will be destroyed and recreated.

The most obvious consequence of having your Activity get destroyed is that all of the views also have to be recreated, but the most serious consequence is that all state stored in the Activity (meaning your fields and properties) will be lost, and a brand new instance of your Activity class will be created from scratch instead.

Handling Configuration Changes

There are a few approaches to dealing with this problem:

  1. Disable the behavior
  2. Serialize and deserialize your state
  3. Use a retained Fragment

The first option is to disable this behavior, which can be done by setting the configChanges property of the Activity to the configuration changes that you don’t want to cause the Activity to be destroyed. This seems like a great option, and you will find many people recommending it. However, Google discourages this approach:

This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

The second option was the best approach for a while, and many apps no doubt still use this approach. When an Activity is being destroyed for a configuration change it will receive a call to OnSaveInstanceState. This method has Bundle argument that can be used to stash data using a key/value system. Basic types are supported by default, but more complex data types are difficult to deal with. Once the new Activity is created it will receive a call to OnRestoreInstanceState, which is handed the same Bundle object in order to fetch the stashed data.

The downside of this approach is that it is tedious and error prone. If you forget any fields then your application will have subtle bugs any time a user rotates his device. Ideally we could just throw a whole object from the old Activity to the new one. In fact, there is a deprecated API for doing just this (see OnRetainNonConfigurationInstance and GetLastNonConfigurationInstance), but that mechanism has been replaced by a better one.

Since Android 3.0 the current recommended solution to dealing with configuration changes is with a retained Fragment.

Fragments

A Fragment is kind of like a miniature Activity. It has a lifecycle, state, and optionally a view hierarchy. A Fragment is attached to an Activity via the Activity‘s FragmentManager.

By default whenever an Activity is destroyed for a configuration change its associated Fragments are also destroyed. However, you can request that a Fragment be retained by setting the RetainInstance property to true, which allows the entire object and all of its fields (but not its views) to be reused.

Therefore, the best technique for dealing with configuration changes is to actually move most of your Activity‘s code into a Fragment instead. The Activity is then merely a dumb shell used to create the Fragment and deal with Activity-specific issues like Intents. Here is an overview of how this technique works:

  1. When the Activity is created it uses its FragmentManager to search for an existing instance of its Fragment (identified by a tag string).
  2. If an existing Fragment was not found then a new one is created and added to the Activity.

Other than dealing with things like Intents and results from other Activitys (both to be covered in future segments of this series) the Activity class doesn’t have much else to do. As you can imagine, the code to perform these steps will end up looking fairly boilerplate. In fact, this is a great opportunity for some code reuse.

Example

As an example of how to deal with this problem in a generic way let’s start with the Xamarin.Android stock template that you get when you create a new application. If you run this template without any modifications then you get a simple application with a button on it. When you click the button it shows you how many times it has been clicked. In order to demonstrate the problem click the button a few times and then rotate the device. The first thing you’ll notice is that the button text reverts to the original “Hello World” text. If you click the button again you’ll also notice that the count starts over. This is the bug we will be fixing.

In order to fix this we will introduce two new base classes: FragmentActivity and FragmentBase. These classes can be dropped in to any application, and we will build on them further throughout this series to add other useful capabilities. For this problem, though, the classes are pretty simple. Here is the code:

/// <summary>
/// An Activity that uses a retained Fragment for its implementation.
/// </summary>
public abstract class FragmentActivity<TFragment> : Activity where TFragment : FragmentBase, new()
{
/// <summary>
/// The top-level fragment which manages the view and state for this activity.
/// </summary>
public FragmentBase Fragment { get; protected set; }

/// <summary>
/// The tag string to use when finding or creating this activity's fragment. This will be contructed using the type of this generic instance.
/// </summary>
protected string FragmentTag
{
get
{
return GetType().Name;
}
}

/// <inheritdoc />
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

LoadFragment();
}

/// <inheritdoc />
public override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
Fragment.OnAttachedToWindow();
}

/// <inheritdoc />
protected override void OnNewIntent(Intent intent)
{
Fragment.OnNewIntent(intent);
}

/// <summary>
/// Loads the fragment for this activity and stores it in the Fragment property.
/// </summary>
protected virtual void LoadFragment()
{
Fragment = FragmentBase.FindOrCreateFragment<TFragment>(this, FragmentTag, global::Android.Resource.Id.Content);
}

/// <inheritdoc />
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
Fragment.OnActivityResult(requestCode, resultCode, data);
}
}

/// <summary>
/// The base class for top-level fragments in Android. These are the fragments which maintain the view hierarchy and state for each top-level
/// Activity. These fragments all use RetainInstance = true to allow them to maintain state across configuration changes (i.e.,
/// when the device rotates we reuse the fragments). Activity classes are basically just dumb containers for these fragments.
/// </summary>
public abstract class FragmentBase : Fragment
{
/// <summary>
/// Tries to locate an already created fragment with the given tag. If the fragment is not found then a new one will be created and inserted into
/// the given activity using the given containerId as the parent view.
/// </summary>
/// <typeparam name="TFragment">The type of fragment to create.</typeparam>
/// <param name="activity">The activity to search for or create the view in.</param>
/// <param name="fragmentTag">The tag which uniquely identifies the fragment.</param>
/// <param name="containerId">The resource ID of the parent view to use for a newly created fragment.</param>
/// <returns></returns>
public static TFragment FindOrCreateFragment<TFragment>(Activity activity, string fragmentTag, int containerId) where TFragment : FragmentBase, new()
{
var fragment = activity.FragmentManager.FindFragmentByTag(fragmentTag) as TFragment;
if (fragment == null)
{
fragment = new TFragment();
activity.FragmentManager.BeginTransaction().Add(containerId, fragment, fragmentTag).Commit();
}

return fragment;
}

/// <inheritdoc />
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);

RetainInstance = true;
}

/// <summary>
/// Called when this fragment's activity is given a new Intent.
/// </summary>
/// <remarks>The default implementation does nothing</remarks>
public virtual void OnNewIntent(Intent intent)
{
}

/// <summary>
/// Called when this fragment's activity is attached to a window.
/// </summary>
/// <remarks>The default implementation does nothing</remarks>
public virtual void OnAttachedToWindow()
{
}
}

As you can see, FragmentActivity is a generic abstract class with a type parameter to specify the type of the Fragment that it should use. This class creates and holds on to the Fragment and forwards a few useful messages to the Fragment that otherwise would be handled by the Activity. The FragmentBase class is an abstract class that is used as the base class for any Fragments used by a FragmentActivity. Its static FindOrCreateFragment method, as its name implies, is used to find an existing instance of a Fragment or create a new one if one is not found. Also note that RetainInstance is set to true when this Fragment is created, which is the key to allowing the instance to be reused. The other methods are just there to receive notifications from the Activity.

The way you use these classes is simple. For each Activity you will create a pair of classes: a Fragment that inherits from FragmentBase and an Activity that inherits from FragmentActivity. The generic type argument links them together. In many cases the Activity doesn’t need any additional code (it will just be an empty class), and all of the important code goes in the Fragment. To see this in action this is how I adapted the Xamarin.Android template to use these new classes (complete code):

[Activity(Label = "FragmentActivityTest", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : FragmentActivity<MainActivityFragment>
{
}

public class MainActivityFragment : FragmentBase
{
private int _count = 0;
private Button _button;

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.Main, container, attachToRoot: false);

_button = view.FindViewById<Button>(Resource.Id.myButton);

if (_count != 0)
{
UpdateButtonText();
}

_button.Click += delegate
{
_count++;
UpdateButtonText();
};

return view;
}

private void UpdateButtonText()
{
_button.Text = string.Format("{0} clicks!", _count);
}
}

The first thing you’ll notice is that, as I mentioned before, the Activity has no code in it. Looking at the Fragment you’ll notice that it looks very similar to the original code, but with a few key tweaks. Let’s look at what I had to change.

The first change was the loading of the layout file. The original code looked like this:

SetContentView(Resource.Layout.Main);

SetContentView is a method of Activity, but we’re not in an Activity anymore. Instead, we just have to load the layout and return it. For this purpose we are given a LayoutInflater, and we use it like this:

var view = inflater.Inflate(Resource.Layout.Main, container, attachToRoot: false);

There are two additional arguments being used here, and both are important. The first is the container ViewGroup that is passed to us as an argument to OnCreateView. This is the container in which the view we return will be inserted. The second is a boolean that tells the LayoutInflater that we don’t want it to insert the inflated view into that container.1

Moving on, we have an extra bit of initialization code:

if (_count != 0)
{
UpdateButtonText();
}

This code is necessary because while the Fragment is reused across configuration changes the view is not. That means this method will be called multiple times on the same Fragment instance2, and it is up to us to initialize the view with the current state3. In order to handle this I created a field for the button and refactored the code for updating the text into a method that I can call in multiple places. Since the initial text comes from the layout file and doesn’t match the format used after clicking the button I check first to see if the button has ever been pressed.

Lastly, I return the view that was created since that is needed by the Activity in order to insert it into the view hierarchy.

Summary

As you can see, this approach makes it very easy to handle configuration changes by mostly just ignoring them. The only remaining wrinkle is that the views are still destroyed and recreated, which requires a bit of extra initialization. This is necessary because the views may actually adapt to the configuration change. The good news is that we no longer have to tediously save and restore every state field.

I use this technique in every Android application I write, and it works very well. I hope that this post and the example code will help you save time dealing with the same issue.

In the next part of this series I will explain how to deal with the problem of starting a new Activity and waiting for its results.


  1. This may seem strange. Why are we passing in the container if we aren’t inserting the view into it? It turns out that there is a good reason for this, which is explained in detail by this article. If you leave off the last argument the default is true, and you will get an exception because the view is inserted twice. If you pass null as the second argument then you won’t crash, but your top-level LayoutParams in your layout file will be ignored. Thus we pass in the container and we tell it not to attach. 

  2. There is a corresponding method OnDestroyView, which can be used to do any necessary cleanup when the old view is destroyed during a configuration change (or when the Fragment itself is going to be destroyed). 

  3. Some views do their own saving and restoring of temporary state during configuration changes. For instance, an EditText will save the text that has been entered, the cursor location, and the current selection. This is handled by OnSaveInstanceState and OnRestoreInstanceState in the View class