Android provides a rich development environment for the developers. It has many widgets built in which can satisfy the needs of the developer. Even if those element cannot full fill developer's requirements; they can still be easily extended to fit the requirement.
One such example would be the Custom ListView. Android provides ListView element to display items in a vertical scrolling list. User can navigate through that list and can perform action such as Tap, Long Tap or double Tap.
But what if we need to change the default list view? What if we need to add custom element into the view along with the text? This can be easily achieved through extending the Adapter class in android.
One popular Adapter type is ArrayAdapter which can be extended to provide custom view to the list view.
You can think the Adapter class as the Content Provider for the list view. Every listview has an associated Adapter which provides data to populate it's view. If the ListView requires to display a item on it's list, it asks the Adapter to fill it's view for that position. Adapter then fill up the view and return the view to the list view. That view is shown to the user.
So lets get down to business !!!
You will need to define two layout xml for your custom layout. Because the layout works like just below -
So, Generally ListView will reside in the main.xml which is our view for this Activity.
And rowlayout.xml will be used by our extended ArrayAdapter to populate and return a single row element in the list whenever the list asks for it.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/countryLV"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>
And our row element layout -
rowlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imgV"
android:maxWidth="100dip"
android:maxHeight="75dip"
android:layout_width="100dip"
android:layout_height="75dip"
/>
<LinearLayout
xmlns:andxmlns="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/txtV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40px"
android:textStyle="bold"
/>
<TextView
android:id="@+id/txtVDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20px"
android:textStyle="italic"
/>
</LinearLayout>
</LinearLayout>
Important lines are marked red with underline to highlight them. Most of them are under "android:id" tag, this tag is used to reference back to this element in java code.
Thing to notice is how the layout is formed, First we took a horizontal layout, this way our elements will be added horizontally. Then we add our image, which will be left of our row. Next again we add a vertical layout; this ensures the addition of two text elements will be arranged vertically just beside the image.
Next is our Java Code, we need two classes. One is our version of ArrayAdapter and another is the actual Activity class.
First our version of ArrayAdapter
MySimpleAdapter.java
public class MySimpleAdapter extends ArrayAdapter<String>{
private final Context context;
private final String [] values;
public MySimpleAdapter(Context context, String [] values) {
super(context, R.layout.rowlayout, values);
this.context = context;
this.values = values;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView tView = (TextView)myView.findViewById(R.id.txtV);
TextView tVD = (TextView)myView.findViewById(R.id.txtVDescription);
tVD.setText(values[position]);
ImageView imgView = (ImageView) myView.findViewById(R.id.imgV);
tView.setText(values[position]);
imgView.setImageResource(R.drawable.icon);
return myView;
}
}
As you can see that our Adapter class extends the ArrayAdapter<String>. We passed the elements in the constructor of this class which is again passed to the super class.
The most important function to override is the getView method. Whenever the list view wants to populate its view, it will ask our adapter through this method. In this method we inflate a view based on row layout and fill up the elements in it. And then return the inflated view. This view is then shown by the listview element. 2nd parameter of this method, convertView, is used to recycle the view. But we left it for simplicity.
Last class will be our actual activity -
ListViewLearn2Activity.java
public class ListViewLearn2Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.countryLV);
String[] values = new String[] { "Item1", "Item2", "Item3", "Item4", "Item5", "Item6",
"Item7", "Item8", "Item9", "Item10", "Item11", "Item12"};
MySimpleAdapter adapter = new MySimpleAdapter(this, values);
lv.setAdapter(adapter);
}
}
Trivial stuffs here.
So, this concludes the demonstration of how easily you can create your own custom list view in android.
Let me know your thoughts.
Download entire project here.