Skip to main content

Custom List View

Some Times we may come across few situations where we need to display an image and information about the image beside it.
consider the following image as an example : 

This task can be accomplished in many ways and am gonna discuss a way using Base Adapter.

In general a list view will contain only a single textview in each row  which will be inflated (by default) for the number of items. But if we need another view other than a textview or an additional view we need to use an alternative.

This inflation is done by using an additional xml file which will be inflated onto the list view.
consider an xml file with a list view as below :

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" >
   
  <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    
     <ListView
        android:id="@+id/main_LV_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>
</LinearLayout>

And we are going to inflate the following xml file so that we can get an image and a textview in each row .
row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/row_IV_android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/row_TV_detail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

Now let us consider how to use the BaseAdapter class
we need to use a class which extends the baseAdapter class.
After extending the baseadapter class we need to add the 4 unimplemented methods of baseAdapter.

Consider the following code : 
  1. class CustomAdapter extends BaseAdapter {
  2. Context cont;

  3. public CustomAdapter(Context c) {
  4. // TODO Auto-generated constructor stub
  5. cont = c;
  6. }

  7. @Override
  8. public int getCount() {
  9. // TODO Auto-generated method stub
  10. return 5;
  11. }

  12. @Override
  13. public Object getItem(int arg0) {
  14. // TODO Auto-generated method stub
  15. return arg0;
  16. }

  17. @Override
  18. public long getItemId(int arg0) {
  19. // TODO Auto-generated method stub
  20. return arg0;
  21. }

  22. @Override
  23. public View getView(int arg0, View arg1, ViewGroup arg2) {
  24. // TODO Auto-generated method stub
  25. View v = arg1;
  26. LayoutInflater lv = (LayoutInflater) cont
  27. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  28. v = lv.inflate(R.layout.row, arg2, false);
  29. ImageView iv_android = (ImageView) v
  30. .findViewById(R.id.row_IV_android);
  31. TextView tv_label = (TextView) v.findViewById(R.id.row_TV_detail);
  32. tv_label.setText(" label is " + arg0);
  33. return v;
  34. }
  35. }
  36.  
The getView() is used to inflate the image and the textview to the listview.
getCount() is used to identify the number of items that should be displayed in the list view.
We can consider a arraylist and specify the size of the arraylist so that the getView() will be called for all the list items , thereby displaying a row for each arraylist item.


Now how to use this above code to make it display the listview?


Its similar to setting an adapter for a listview but here the adapter will be an object of the class that extends the BaseAdapter.


i.e.., we use 

listView.setAdapter(new CustomAdapter(this)) instead of  
listView.setAdapter(adapter);
Once have a look at the line 34 :
Here we can see that we are inflating the row.xml file as a view and finally returning the view.

consider the entire code below : (I am not extending a ListActivity. Dont do it)
  1. import android.widget.Toast;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.os.Bundle;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.AdapterView;
  9. import android.widget.AdapterView.OnItemClickListener;
  10. import android.widget.BaseAdapter;
  11. import android.widget.ImageView;
  12. import android.widget.ListView;
  13. import android.widget.TextView;

  14. public class CustomListsActivity extends Activity implements
  15. OnItemClickListener {
  16. /** Called when the activity is first created. */
  17. ListView listView;

  18. @Override
  19. public void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.main);
  22. listView = (ListView) findViewById(R.id.main_LV_list);
  23. listView.setAdapter(new CustomAdapter(this));
  24. listView.setOnItemClickListener(this);
  25. }

  26. class CustomAdapter extends BaseAdapter {
  27. Context cont;

  28. public CustomAdapter(Context c) {
  29. // TODO Auto-generated constructor stub
  30. cont = c;
  31. }

  32. @Override
  33. public int getCount() {
  34. // TODO Auto-generated method stub
  35. return 5;
  36. }

  37. @Override
  38. public Object getItem(int arg0) {
  39. // TODO Auto-generated method stub
  40. return arg0;
  41. }

  42. @Override
  43. public long getItemId(int arg0) {
  44. // TODO Auto-generated method stub
  45. return arg0;
  46. }

  47. @Override
  48. public View getView(int arg0, View arg1, ViewGroup arg2) {
  49. // TODO Auto-generated method stub
  50. View v = arg1;
  51. LayoutInflater lv = (LayoutInflater) cont
  52. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  53. v = lv.inflate(R.layout.row, arg2, false);
  54. ImageView iv_android = (ImageView) v
  55. .findViewById(R.id.row_IV_android);
  56. TextView tv_label = (TextView) v.findViewById(R.id.row_TV_detail);
  57. tv_label.setText(" label is " + arg0);
  58. return v;
  59. }
  60. }

  61. @Override
  62. public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
  63. // TODO Auto-generated method stub
  64. Toast.makeText(this, "item clicked is " + arg2, Toast.LENGTH_SHORT)
  65. .show();
  66. }
  67. }

The above code also has an implementation of displaying a toast when a list item is clicked. 

Any suggestions are welcomed.
Please do comment if any problem with the code.

Comments

Popular posts from this blog

Image Slide Show

Hi everyone. In this tutorial i am going to show you all the code which when run will display the images as a slideshow. Below is the attached screen shot :  For this i am considering the images from the Sdcard's images folder where i am having all the images. Next to display the images i am using View Flipper concept. I am adding ImageViews to the viewflipper so that the images can be displayed onto the screen. Now lets start  Design an xml layout as below (say main.xml) <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent" >     <ViewFlipper         android:id="@+id/main_flipper"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"  

Template literals

Template literals: ES6   introduced many cool things among which one is ‘ Template literals ’   This is a new way of representing strings.    Normally we use either “(double quotes) or ‘(single quote) to represent a string in  JavaScript .   For example:   var name=”literal”;   Or    var name=’literal’;   But from ES6 there is a new way of doing it. We can use `(back tick) symbol which is present left to key ‘1’ in keyboard.    Ie.,   var name = `literal`;   Well when we already have “(double quotes) or ‘(single quote), what extra does `(back tick) do?   Template literals  shines well when we have some concatenation of strings or when creating multi-line strings.   Look at below to understand the power of Template literals.   Let's  take an example where we need to form a string where you are forming a string based on a button clicked. For example - “You clicked on login button”.     Old way:   var 

Localization using .ttf files

In my previous post  here  i gave some information on how to use the concept of localization for the languages that are supported by Android. Now suppose if u want to display a language that is not supported by android.......? Then what might be solution? I will be discussing a small example for doing this now. Suppose if you want to display some text like this " हिंदी " or  " தமிழ் " or  some thing like the text   here  any other language that is  not supported by android we can use .ttf files so that we can print the font we are interested. To achieve this first we need to download few .ttf files. You can google for a file you need, download it and place this into the assets folder. In the picture i am having few other ttf files which i included, But for the time being only the DroidSansRegionalAAd.ttf is discussed by me which i used to display the words of few languages of India as in the following picture. Now we need to refer to the ttf file i