Layouts

Presenter – Part 1

On 26th November 2011 I presented a keynote at AndroidConf Brasil about Android layouts. For my presentation, I used a custom Android application running on a Samsung Galaxy 10.1 Tablet instead of the more traditional Powerpoint / KeyNote approach. Instead of publishing my slides following my presentation, I am publishing a “lite” version of this and, in a break from the normal format of this blog, in this series of articles I am going to explain some of the key aspects of the app. Having said that, the lite version is almost entirely UI, so should be of interest to regular readers.

Before I go any further, I should point out that the inspiration for my approach came from a Google I/O 2011 presentation by Google Developer Advocate Reto Meier where he ran a presentation from two Xooms linked by USB, and he live tweeted during his presentation. Reto later blogged about how it worked. I thought that would work well for my presentation, but was unable to find out if Reto had ever open-sourced it, as he suggested he would in his blog. I was left with the choice of either writing my own, or using a currently available package such as PowerPoint or Google Presentations, which would not allow me the ability to live tweet, or remote control the app. I reasoned that if I were to write my own app, I could actually create the slides as Android Layouts which, given that I intended to speak about Android Layouts, had a symmetry to it that really appealed to me.

Firstly, I should explain that the code being released is a stripped down version of the actual app that I used. The actual app allowed me to remote control the presentation from another Android device over Bluetooth, and also enabled me to tweet during the presentation to provide links relevant to the subject currently being spoken about. I am not releasing the full source because this blog focusses on UI matters, and I wanted to keep the code as UI focussed as possible as I do not feel that it would be in the true spirit of “Styling Android” to start explaining Bluetooth and Twitter APIs.

It is also worth pointing out that, at the time of writing. I have not tested this on a device other than the Galaxy Tab. In true agile style, I developed precisely what I needed, and that was to run on the Tablet. It is for this reason alone that I’ve set the MinSdk version to 11. Having said all of that, any fixed sizes and dimensions have been put in to res/values/dimens.xml, so adapting things to work on other devices should not be too much of a problem. In time, I may update the source to support other devices.

Let’s begin with a quick look at the Manifest:

[xml]








[/xml]

There’s a single permission, WAKE_LOCK which we’ll cover in due course. In the element we are specifying a theme that we use throughout the app, and also setting android:hardwareAccelerated=”true”. As we’re targeting the Galaxy Tab, we want to ensure that we’re using the GPU to keep our animations and transitions nice and smooth.

Within this app I’ve made use of Fragments to make slide transitions really easy, but to ensure a degree of backward compatibility (and no extra work) I used the Fragment implementation from the Android Support Library rather than the native Honeycomb implementation.

The app consists of a single Activity named StandaloneDisplayActivity which is really rather simple. It acquires a WakeLock to prevent the device from going to sleep – I didn’t want the screen going blank while I was in the middle of my presentation. The WakeLock requires the permission that we saw in the Manifest. We acquire a WakeLock during onResume(), and release it in onPause().

In our onCreate() method, we set the content view to a layout defined in R.layout.display, and then look up a view which we cast to DisplayLayout, which is a custom Layout that is responsible for displaying a presentation. We’ll examine this in detail later on. We also hide the system and action bars because I didn’t want them appearing on the projected image.

Finally, we override onTouchEvent() to call the advance() method on our DisplayLayout instance. This effectively moves to the next slide or slide phase (more on slide phases later on) by touching the screen.

[java] public class StandaloneDisplayActivity extends FragmentActivity
{
public static final String TAG = “PresenterLite”;

private WakeLock wakeLock;
protected DisplayLayout display = null;

@Override
protected void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );

PowerManager pm = (PowerManager) getSystemService( POWER_SERVICE );
wakeLock = pm.newWakeLock( PowerManager.FULL_WAKE_LOCK, TAG );
setContentView( R.layout.display );
display = (DisplayLayout) findViewById( R.id.display );
display.setSystemUiVisibility( View.STATUS_BAR_HIDDEN );
getActionBar().hide();
}

@Override
protected void onResume()
{
super.onResume();
wakeLock.acquire();
}

@Override
protected void onPause()
{
wakeLock.release();
super.onPause();
}

@Override
public boolean onTouchEvent( MotionEvent event )
{
if( event.getAction() == MotionEvent.ACTION_UP )
{
display.advance();
return true;
}
return super.onTouchEvent( event );
}
}
[/java]

Now let’s move on to the layout that out Activity loads from res/layout/display.xml. I’m not going to include this in full here, because it is quite large and is really just defining the background layout which will appear behind our slides. The key part functionally, is where we define our DisplayLayout instance that we reference in our Activity:

[xml]

[/xml]

I won’t bother explaining the common layout attributes here, as you can find this information elsewhere on this blog. However, we declare a custom namespace named “sap” (short for Styling Android Presenter) and this uses the package of our app in its URI. There are some custom attributes within this namespace, prefixed with “sap”, which are specific to the custom control. These attributes been defined in res/values/attrs.xml:

[xml]




[/xml]

These allow us to specify some custom attributes for our custom control, specifically to allow us to specify animations to run during slide transitions, and also to define a file where we’ll load our list of slides from.

In the next part of this series, we’ll look at our DisplayLayout custom layout, and also some of the other custom controls used within Presenter.

PresenterLite is released under Apache License V 2, and all of the code listed in this article are also bound by the same license.

The source code for PresenterLite can be found here.

© 2011, Mark Allison. All rights reserved.

Copyright © 2011 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.