KDE 4.0 Release Counter

Sunday, December 9, 2007

Android: how to show items with different styles in a ListView

In the Android environment we can visualize ListView items using ArrayAdapter object, which act as interface between textual data representation and ListView. Its constructor accept a layout resource id pointing to a TextView instanced at each data row visualization.
If we have the need to present the various items with different layouts, we can do it in a simple way by using the excellent engineering of the base Adapter class, adapting it for our needs. Let's suppose to want to show an icon next to the textual item description if item text contains a given character sequence, let's say it starts with 'a' character to make a simple example.
First of all we need two View class derived objects to show the data into the ListView. The first one, 'SView1' in our example, simply derives from TextView class and it will be populated with text string passed as parameter in its constructor.

public class SView1 extends TextView {
TextView mText;
public SView1 (Context context, String text)
{
super(context);
setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
setText(text);
}
}

The second one, 'SView2', is slightly more complex and extends LinearLayout, a class designed to group and organize child Views. In SView2 we'll create two children objects, an ImageView to handle the icon, read from the resources, and a TextView which will contains the data strings.

public class SView2 extends LinearLayout {
String Title="";
TextView mText;
ImageView mView;
public SView2 (Context context, String text)
{
super(context);
this.setOrientation(HORIZONTAL);
setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
mView = new ImageView(mContext);
mView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mView.setImageResource(R.drawable.icon);
addView(mView);
mText = new TextView(context);
mText.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
addView(mText);
setText(text);
}
public void setText(String text)
{
mText.setText(text);
}
}

Now we have only to personalize the data hander, Adapter class. We can create a class that extends directly ArrayAdapter<> class. The data handling methods can be inherited from the superclass, by overloading only getView() method, called by parent ListView, at each data row visualization. What we will do in this method is only to check string content, and decide view type, SView1 or SView2 instantiate. Parent ListView can propose us to reuse an existent View object, if we want to use it, we should check that the proposed View type is coherent with data. Final step is in the Activity object: we should instantiate an Adapter e populate it with our data.

I was forgetting: yesterday RubyOnRails 2.0 was born, congratulations.
http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done

Adapter:
public class SimpleStringAdapter extends ArrayAdapter {

public SimpleStringAdapter(Context context, List Items ) {
super(context,R.layout.a,Items);
}
public View getView(int position, View convertView, ViewGroup parent) {
String s = getItem(position);
boolean isType1 = true;
if( s==null )
s = "";
if(s.startsWith("a"))
{
isType1 = false;
}
if(isType1)
{
SView1 theView ;
if((null==convertView )||!(convertView instanceof SView1))
theView = new SView1(super.getContext(),s);
else
{
theView = (SView1)convertView;
theView.setText(s);
}
return theView ;
} else
{
SView2 theView ;
if((null==convertView )||!(convertView instanceof SView2))
theView = new SView2(super.getContext(),s);
else
{
theView = (SView2)convertView;
theView.setText(s);
}
return theView ;
}
}
}

Activity:

public class SimpleView extends ListActivity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);

List items = new ArrayList();
items.add("a riga 1");
items.add("a riga 2");
items.add("b riga 3");
items.add("a riga 4");

SimpleStringAdapter strings =
new SimpleStringAdapter(this, items);
setListAdapter(strings);
}
}

Thursday, December 6, 2007

Life with Android

I was finally able to explore the Android development environment. The first thing I noted is the easy SDK installation process, you only have to unzip a file and to set an environment variable. If you want to use Eclipse as development environment, you need to download a plugin from Google site. A wonderful thing is the porting of the SDK under different Operating Systems: Linux, MacOS and Windows.
The SDK comes with a good emulator included but sometimes, at least in Linux environment, it loses the synchronism with Eclipse in debug phase.
Anyway the tools used under the hood are command line commands, adb in this case, that reside in SDK tools directory, and in a hurry we can kill its process so Eclipse can restart it in its next debug session. The same SDK seems to be the first step toward a more complete system and various features are reporting not working in the project mailing list. All things considered Android is a very good first step, documentation is complete and it covers each toolkit area, but we can expect a good growth. As a pilot project I wrote a little program to read planet.kde.org
feeds, one of my favorite sites. I explored some Android technologies, background services, sqlite database, custom views, and integrated browser, and I enjoyed the system very much, even though I didn't explore multimedia features. The project has been published on Google Code at http://code.google.com/p/planetandroid/ address. The license is obviously GPL.