Tuesday, 10 July 2012

How to best organize your Android source?


One thing that can certainly speed up your development tasks when doing Android projects, is to reuse your Android source code. To do that, it is important to make sure that your Android source code is well organized and easy to find and reuse when you need it. Many of us are forgetting this, when things go fast, and we have to make deadlines. But if you take a little time to find some routines and methods that suits you, it can actually help you reach your deadlines in a lot more comfortable way. If you have ever found yourself writing code, feeling some kind of deja-vu, this post is for you.
There is a few different resources that will be good to keep handy, and to reuse. This includes Java classes, resources (graphic, sound and other assets) and sometimes layouts. The best way to do this, is to use library projects. You could also compile your code into static jars, which is great if you need to share your code with others, without revealing your source.
A library project can contain all of these resources – Java source, assets and XML.

Java source

This is probably the primary thing that you want to reuse and/or share. This would often be your own extension to some classes or libraries. Maybe you wrote your oven ArrayAdapter extension, that you would love to be able to easily reuse and extend further in other projects. Or you made some heavy maths, that you would not want to spend 3 nights writing again.

Resources

Resources like graphics and sounds is often very specific to an application. However, there might be stuff that you would like to be able to easily reuse in other projects. This could be some bullets, frames, background images, list item assets or others. Things that are not necessarily very specific to a single application. If you develop games, it could be some bells, boings or whistles.

XML

This would primarily be layouts, and often be related to entire components, like a specific view that you made, or a widget. It could also be menus, strings and so on.

Organizing your Android source library projects

There is probably as many ways to split up your code into projects, as there is developers around. My approach is to split it up as much as it makes sense to do. That means, do not mix multiple components in one project, but if you make a component, put all of your code in a single project.
1. Specific components. This could be your own TabHost implementation. Or a custom Dialog. If you make such components, the best way to stay organized is to create one library project for each of your components. With that exception, that you might have some very small UI extensions or components, that it does not make sense to put in a project of its own. So, make a UIToolsLibrary with your small comonly used UI tools, and then go for a full library when creating larger components. The way you mix this depends on how you feel about it.
2. Tools. Examples are simple classes or extensions. Maybe an extension to Activity, or other classes. It could also be your own utility methods, like specific math functions, or calculations. You might also want to create multiple libraries for this, for instance your own math library, or your own graphics library. Again, how you organize this is much up to your own feelings. But be ware, that as your code base grows, you will be happy to have started out with an approach that splits up things a lot. A good approach is to create a core tools library, that contains small utility classes related to Android, and then create a library for each of the areas that you are working with.
3. Resources. As mentioned above, resources like graphic and sound are often not reusable. However, if you create a lot of applications, you might want to have some resources handy. The Android SDK has some resources for menus, icons and tabbars. Likewise, you might want to create your own.
4. Layouts. This will often be related to a specific component, and as such rarely be a good idea to create a specific project for these. However, if you do a lot of code, it could be wise. If you have your own ListView items, or custom Dialog boxes, it could make sense. I would, however, put these in the resource project instead.

Creating a library project

Using Eclipse and ADT, this is how you do it:
1. Select File->New->Project
2. Select Android -> Android Project, and click next
New Library project
Type in a project name, application name and package name. Application name would probably be the same as your project name. Select Create Activity and type in an activity name if you wish to create an activity. For this example, we do not. Click Finish.
3. Right-click your project in the Project Explorer, and click Properties. Select Android.
Android Project Properties
The only thing that you has to do here, is select “Is Library”. Then click OK.
Now you can start adding code to your project. Let’s create a small class.
4. Create a class – let’s call it TestClass, and extend Object. In here, create a simple static method:
public class TestClass {
    public static String combine(String a, String b) {
        return a + b;
    }
}
Now save this, and build your library. Our small class is now ready for use in our applications.

Using your libraries

After creating a library, you can start using it.
1. Right-click your application project in the Project Explorer, and select Properties. Select Android.
2. In the Library section, click Add, and your library project (if it is still open) should appear in a dialog. Select it, and click OK.
Select Library Project
3. In your application code, you can now use the TestClass class. Try it out:
String test = TestClass.combine("Hello"" World");
Log.i("Test", test);
The same way, when you include resources and layouts in your library, you can reference it from the application where you include the library.

Tuesday, 15 May 2012

Android User Interface Design: Frame Layouts


Frame layouts are one of the simplest layout types used to organize controls within the user interface of an Android application.

Understanding layouts is important for good Android application design. In this tutorial, you learn all about frame layouts, which are primarily used to organize individual or overlapping view controls on the screen. When used correctly, frame layouts can be the fundamental layout upon which many interesting Android application user interfaces can be designed.

What Is A Frame Layout?

Frame layouts are one of the simplest and most efficient types of layouts used by Android developers to organize view controls. They are used less often than some other layouts, simply because they are generally used to display only one view, or views which overlap. The frame layout is often used as a container layout, as it generally only has a single child view (often another layout, used to organize more than one view).
TIP: In fact, one place you’ll see frame layouts used is as the parent layout of any layout resource you design. If you pull up your application in the Hierarchy Viewer tool (a useful tool for debugging your application layouts), you’ll see that any layout resources you design are displayed within a parent view-a frame layout.
Frame layouts are very simple, which makes them very efficient. They can be defined within XML layout resources or programmatically in the application’s Java code. A child view within a frame layout is always drawn relative to the top left-hand corner of the screen. If multiple child views exist, then they are drawn, in order, one atop the other. This means that the first view added to the frame layout will display on the bottom of the stack, and the last view added will display on top.
Let’s look at a simple example. Let’s say we have a frame layout that is sized to control the entire screen (in other words, layout_width and layout_height attributes are both set to match_parent). We could then add three child controls to this frame layout:
  • An ImageView with a picture of a lake.
  • A TextView with some text to display towards the top of the screen.
  • A TextView with some text to display towards the bottom of the screen (Simply use the layout_gravity attribute to have the TextView “sink” to the bottom of the parent).
The following figure shows what this sort of layout would look like on the screen.
Frame Layout Figure 1

Defining an XML Layout Resource with a Frame Layout

The most convenient and maintainable way to design application user interfaces is by creating XML layout resources. This method greatly simplifies the UI design process, moving much of the static creation and layout of user interface controls and definition of control attributes, to the XML, instead of littering the code.
XML layout resources must be stored in the /res/layout project directory hierarchy. Let’s take a look at the simple frame layout introduced in the previous section. Again, this screen is basically a frame layout with three child views: an image that fills the entire screen, upon which two text controls are drawn, each with the default, transparent background. This layout resource file, named /res/layout/framed.xml, is defined in XML as follows:
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout  
  3.     xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.     <ImageView  
  7.         android:id="@+id/ImageView01"  
  8.         android:layout_height="fill_parent"  
  9.         android:layout_width="fill_parent"  
  10.         android:src="@drawable/lake"  
  11.         android:scaleType="matrix"></ImageView>  
  12.     <TextView  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:textColor="#000"  
  16.         android:textSize="40dp"  
  17.         android:text="@string/top_text" />  
  18.     <TextView  
  19.         android:layout_width="fill_parent"  
  20.         android:layout_height="wrap_content"  
  21.         android:text="@string/bottom_text"  
  22.         android:layout_gravity="bottom"  
  23.         android:gravity="right"  
  24.         android:textColor="#fff"  
  25.         android:textSize="50dp" />  
  26. </FrameLayout>  
Recall that, from within the Activity, only a single line of code within the onCreate() method is necessary to load and display a layout resource on the screen. If the layout resource was stored in the /res/layout/framed.xml file, that line of code would be:
  1. setContentView(R.layout.framed);  

Defining a Frame Layout Programmatically

You can also programmatically create and configure frame layouts. This is done using the FrameLayout class (android.widget.FrameLayout). You’ll find the frame-specific parameters in the FrameLayout.LayoutParams class. Also, the typical layout parameters (android.view.ViewGroup.LayoutParams), such as layout_height and layout_width, as well as margin parameters (ViewGroup.MarginLayoutParams), still apply to FrameLayout objects.
Instead of loading a layout resource directly using the setContentView() method as shown earlier, you must instead build up the screen contents in Java and then supply a parent layout object which contains all the control contents to display as child views to the setContentView() method. In this case, your parent layout would be the frame layout.
For example, the following code illustrates how to reproduce the same layout described earlier programmatically. Specifically, we have an Activity instantiate a FrameLayout and place one ImageView control followed by two TextView controls within it in its onCreate() method:
  1. public void onCreate(Bundle savedInstanceState) {  
  2.     super.onCreate(savedInstanceState);  
  3.     TextView tv1 = new TextView(this);  
  4.     tv1.setText(R.string.top_text);  
  5.     tv1.setTextSize(40);  
  6.     tv1.setTextColor(Color.BLACK);  
  7.   
  8.     TextView tv2 = new TextView(this);  
  9.     tv2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));  
  10.     tv2.setTextSize(50);  
  11.     tv2.setGravity(Gravity.RIGHT);  
  12.     tv2.setText(R.string.bottom_text);  
  13.     tv2.setTextColor(Color.WHITE);  
  14.   
  15.     ImageView iv1 = new ImageView(this);  
  16.     iv1.setImageResource(R.drawable.lake);  
  17.     iv1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));  
  18.     iv1.setScaleType(ScaleType.MATRIX);  
  19.   
  20.     FrameLayout fl = new FrameLayout(this);  
  21.     fl.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));  
  22.     fl.addView(iv1);  
  23.     fl.addView(tv1);  
  24.     fl.addView(tv2);  
  25.     setContentView(fl);  
  26. }  
The resulting screen looks exactly the same as the figure shown previously.

When to Use Frame Layouts

With other powerful layout types like linear layouts, relative layouts, and table layouts at your disposal, it’s easy to forget about frame layout. The efficiency of a frame layout makes it a good choice for screens containing few view controls (home screens, game screens with a single canvas, and the like). Sometimes other inefficient layout designs can be reduced to a frame layout design that is more efficient, while other times a more specialized layout type is appropriate. Frame layouts are the normal layout of choice when you want to overlap views.

Looking at Similar Controls

FrameLayout is relatively simple. Because of this, numerous other layout types and view controls are based upon it. For instance, ScrollView is simply a FrameLayout that has scrollbars when the child content is too large to draw within the bounds of the layout. All Home screen app widgets reside within a FrameLayout.
One notable addition to all FrameLayouts is that they can take a foreground drawable in addition to the normal background. This is done via the android:foreground XML attribute. This could be used for, quite literally, a frame around the underlying views.

Conclusion

Android application user interfaces are defined using layouts, and frame layouts are one of the simplest and most efficient layout types available. The child control(s) of a frame layout are drawn relative to the top left-hand corner of the layout. If multiple child views exist within the frame layout, they are drawn in order, with the last child view on top.