Some time ago, while working on some Linux projects requiring GUIs for some commands I've started
autoglade, an Open Source project aiming to fill some gap between scripts and command line utilities and GUIs.
As a proof of concept, I'm wondering if a similar approach would be possible in Android, so let's find out what can be done.
Your comments and suggestions are greatly appreciated.
autoglade
autoglade's main objective is to automate as much as possible the design and implementation of Gnome/GTK based, cross platform applications whose
GUI is designed with
Glade.
A clear idea of what
autoglade is about can be obtained taking a glimpse at
autoglade tutorial: first steps (problems with SF's wiki ? access this
Google cached version) .
More in-depth treatment of autoglade features and a very interesting cross-platform example,
autoeditor, can be found at
autoglade features.
autoandroid
Would it be at all possible to take a similar approach to streamline
android UI design and implementation, factoring the repetitive tasks you have to write again and again for many applications ?
autoandroid library is distributed as a jar file that you can add to your android project java build path.
introductory example
This introductory example provides some automatic behavior of UI components.
Our objective is to obtain,
writing as less code as possible, the following functionality.
A standard
Activity displays our custom
Dialog once the
Button is clicked
The custom
Dialog displayed has an
EditText and a
Button. The
EditText starts empty and the
Button disabled.
Once some text is entered the
Button is activated. If the text is deleted the
Button returns to its disabled state.
When the
Button is pressed the text entered in the
EditText is displayed by the main
Activity using a
Toast, that is we are easily getting the exported values from the Dialog.
dialog_sample.xml
This is the layout of our sample dialog.
We can do it as we normally do using ADT's Layout Editor.
However, to provide the extra behavior we have to add some properties in the XML view of the editor.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:auto="http://schemas.android.com/apk/res/com.codtech.android.samples.autoandroid"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:orientation="vertical"
android:id="@+id/Root">
<com.codtech.android.auto.view.AutoEditText android:id="@+id/EditText01"
android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_margin="6dip"
auto:export="true"
auto:name="text"
auto:sensitize="@+id/Button01"
android:hint="@string/edittext_hint" />
<Button android:id="@id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="OK" android:width="150dip"
android:layout_gravity="right"
android:enabled="false"
android:clickable="false"
auto:dialog_action="positive" />
</LinearLayout> |
Let's explain the changes:
Define the namespace auto. The name that appears after http://schemas.android.com/apk/res is usually the package name of your application and will be used in an attribute definition (attrs.xml). More on this later.
The root layout must have an ID as it's used by some methods in the library and should be identifiable. The name here is Root but it could be whatever you like, though Root seems to be a good option.
Instead of EditText we use com.codtech.android.auto.view.AutoEditText which is a class that extends EditText and provides some automatic behavior. As you can see, this usually doesn't affect how the layout is displayed in the editor.
Mark the AutoEditText as exported so we can obtain its value later. This is achieved using auto:export="true".
As it is exported we give it a name, text in this case, to obtain the value later. auto:name="text" does the trick.
We automatically sensitize Button01 depending on the content of this EditText. Note that here we are assigning the ID to the Button using @+id because it has not yet been defined and we want to create the ID.
Mark Button01 as the positive action of the Dialog using auto:dialog_action="positive"
Styleable attributes
The way we are adding these attributes is by defining styleable attributes in a file usually attrs.xml.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.codtech.android.samples.autoandroid">
<attr name="name" format="string" />
<attr name="init" format="string" />
<attr name="sensitize" format="reference" />
<attr name="show" format="reference" />
<attr name="update" format="reference" />
<attr name="export" format="boolean" />
<attr name="dialog_ok" format="boolean" />
<attr name="dialog_action" format="string" />
</declare-styleable>
</resources> |
AutoAndroidSamples.java
This is our sample Activity.
package com.codtech.android.samples.autoandroid;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.codtech.android.auto.app.AutoDialog;
public class AutoAndroidSamples extends Activity implements OnClickListener, OnDismissListener {
private AutoDialog ad;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.samples);
((Button) findViewById(R.id.Button01)).setOnClickListener(this);
}
@Override
public void onClick(View v) {
ad = new AutoDialog(this, R.layout.dialog_sample,
R.string.dialog_sample_title);
ad.setOnDismissListener(this);
ad.show();
}
@Override
public void onDismiss(DialogInterface arg0) {
if ( ! ad.isCanceled() ) {
Bundle bundle = ad.getAutoBundle();
Toast.makeText(this, "Entered value: " +
bundle.getString("text"), Toast.LENGTH_SHORT)
.show();
}
}
} |
Set the layout to samples, a simple layout containing the button to display the Dialog when clicked
Set the OnClickListener on this Button
On the onClick handler create the AutoDialog using dialog_sample layout shown previously and a title we defined in strings.xml
Set the OnDismissListener of the AutoDialog
On the onDismiss handler check if the AutoDialog was canceled, a value that is automaticaly set, and if not get the Bundle containing the exported values, extract the String for "text" and display it as a Toast.
Conclusion
We have just scratched the ice.
There are some limitations imposed by the SDK, for example there's no a way to specify a list of resource ids in a styleable attribute, so if we want to update or sensitize a list of Views depending on the state of other View we need to find another way of doing it.
Anyway, this is an extremely simple example of AutoAndroid and its common use. Some other samples will follow demonstrating other features like Pizza Shop which is also an autoglade sample.
If you have comments, ideas, critiques or whatever just drop me a line or leave a comment in the blog.
Copyright © 2009 Diego Torres Milano. All rights reserved.