If you don't find Views by id, Views will find you

Written by Xavier Gouchet - 11 july 2012 - no comments

One of the first thing an Android developer has to learn, it's to match Views declared in an XML layout to fields in the Activity class. Something that looks like this, repeated for all the views you need to manipulate from your activity.


class MyActivity extends Activity {

    private Button myButton; 

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample_views);
        myButton = (Button) findViewById(R.id.myButtonId);
    }
}

Now this can be quite troublesome, and could be automatized. So here it is, a class to help you fill in your fields. You can download it or fork it directly from GitHub.

The use can be pretty simple, and is just two lines, whatever the number of views you may have :


class MyActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);

        ViewFieldMatcher matcher = new ViewFieldMatcher(R.id.class);
        matcher.matchViews(findViewById(android.R.id.content), this);
    }

This code will automatically match any view to the corresponding field, matching the id name to the field's name.

Master On/Off Preferences with Ice Cream Sandwich

Written by Xavier Gouchet - 27 june 2012 - 5 comments

One of the easiest thing to do with android is storing user preferences. It can be as simple as a single xml files and a few lines of code. Since the first version of Android, you have access to several common preference widgets, such as checkboxes, text fields, or even lists.

In Android ICS, new widgets were introduced, among which the SwitchPreference, looking a lot like the iOS famous SwitchButton. If you have paid attention to the Android Design website, you have noticed that Google encourages you to use a Master On/Off switch in the way they used it with the Wifi Preference screen. Here's a reminder for those of you without an ICS device.

Android's Wifi Settings master On/Off Switch

The Wifi can be enabled from the first screen, using the Switch widget. And when you press the Wifi row, you land on the Wifi Preferences screen, where you can select a Wifi Network. At the top of the second screen, you still have a Switch widget to turn the Wifi off if you need to.

Now the question is : how did they do it ? Moreover, how can I do the same in my own preferences ? This is what we're gonna learn in this article. In a fictive video game, here's the preference screens we wan't to see. I'll limit the article to those two screens, others can be done easily after that. This code will only work with API level 14 or higher, so if you're targeting lower devices, be carefull and keep an old fashioned preference screen

The main preferences screen The sound preferences screen

For this article, I dug into the source code of Android's Settings application, so most of this is from Google. The probleme can be divided in two parts. First having the Switch widget at the top of the screen in the second screenshot. This is simply done by using a Switch view in the Custom View of the ActionBar. Then, there is the trickier part of having a preference linking to the second screen and having a Switch widget. You can usually have one or the other, using a PreferenceScreen or a SwitchPreference tag in your xml file. Here, we'll use the Header class introduce in ICS, with a custom adapter (basically almost like having a custom ListView, but with predefined behavior).

To create these screens, we need severall files, so instead of copy pasting all the code in here, I bundled a sample project available for download here.

Here's a list of the files you'll find in the archive, and a little description of what they do :

my_prefs_headers.xml
this file describes the headers of the first screen, meaning each row which links to another PreferenceScreen. Each header can have a title of course, an icon, an id, and a fragment class, defining the PreferenceFragment which will be loaded to display the PreferenceScreen.
MyPrefsActivity.java
the main PreferenceActivity, which loads first our headers, then will load a fragment when a header is clicked.
MyPrefsHeaderAdapter.java
this is the ArraAdapter which will load the Layouts we want for our headers. If you've already worked with ListViews, this should look familiar. This adapter uses 3 different layouts, one for categories sections, one for common header and one for switch header. The "magic" happens in the getHeaderType() method, in which we define which layout should be used with each header.
SoundEnabler.java
this class is mostly a utility we use to bind a Switch widget with the corresponding shared preference. It is linked with the switch defined in the ArrayAdapter described above.
SoundsPreferencesFragment.java
a PreferenceFragment which is used by our Sound header. Nothing much goes here, we mostly load the PreferenceScreen description from an XML file. Also, as described earlier, we create a Switch widget which we had to the ActionBar, and link it to a SoundEnabler instance.

Now, you have a preference screen with a Switch widget, and what's nice is that this trick can work with any other widget than a switch. You just need to create the layout, add it in the Array Adapter and Voila ! If you have any question on this article, please contact me

Download the sample code

What do you want for beakfast ? Just toasts...

Written by Xavier Gouchet - 24 february 2012 - no comments

Toasts ?

Toasts are the usual way to give feedbacks to the user without impacting his experience. The message pops, without having to click on a button to close it.

Usually, a toast can be created using a single line, looking a bit like this, either using a string or with a string resource id (which is better if you want localization).


Toast.makeText(context, "Hello toasts", Toast.LENGTH_SHORT).show();
Toast.makeText(context, R.string.hello_toasts, Toast.LENGTH_SHORT).show();

Android toast with default layout

Custom Toasts

Android also provides a way to have a completely custom view instead, and have all you want, text, images, etc...


LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_layout, null);

// here customize the content of the layout

Toast toast = new Toast(context);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

Android toast with custom layout

Anything else ?

Both methods are quite straightforward, but the second method requires a lot of work. And when you only want to change a tiny details in the default toast, for example the text color, how can you do ?

The idea is to get the TextView created by the default Toast and edit its parameters, like this


Toast toast = Toast.makeText(this, resId, Toast.LENGTH_SHORT);
TextView v = (TextView) toast.getView().findViewById(android.R.id.message);

v.setTextColor(Color.RED);
toast.show();

Android toast with customized default layout

More ...

You can find more information on toasts in the Android documentation.

A robot with a brush : using Paint on Android (Part 1)

Written by Xavier Gouchet - 08 february 2012 -

It's rather common to work with the Canvas when building an app or a Live Wallpaper on Android. The canvas can seem very simple at first, but the Paint class can offer a lot more than what you may think.

The first thing one uses the Paint for is to draw primitives. The Canvas class comes with a limited number of primitives (which you can draw using the drawXXX(...) method). These primitives are shown in the image below : Arcs, Circles, Ovals, Lines, Points, Rectangles (with or with round corners) and text.

Blur

When drawing each primitive, a Paint instance is require, to define the color, the style (do we paint the outline, the filling, or both), and severall basic options like antialising and image filtering. But we can also add some effects on the Paint to enhance the basic primitives. For instance, blur the primitives a little, using one of the following lines (corresponding images below).


paint.setMaskFilter(new BlurMaskFilter(5, Blur.NORMAL)); 
paint.setMaskFilter(new BlurMaskFilter(5, Blur.SOLID));
paint.setMaskFilter(new BlurMaskFilter(5, Blur.INNER));
paint.setMaskFilter(new BlurMaskFilter(5, Blur.OUTER));

Emboss

This effect was really trendy in the 1990s internet, and still in most Powerpoint slideshows. The emboss will make anything look like a 3D object, with simulated highlight and shadow on the edges (like on the image below).


paint.setMaskFilter(new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.5f, 4.0f, 10.0f));

Shadow

Another trendy effect is the shadow, to simulate a ... well you guessed, a shadow on the canvas behind the primitive being drawn.


paint.setShadowLayer(5, 10, 5, Color.LTGRAY);