Thursday, August 25, 2016

Android Custom ListView. (How to customize an Android ListView.)



1. Android Custom ListView.

In the previous article [Android ListView. (How to use an Android ListView)], I explained that what ListView is and how to use it. But the ListView that I explained consists of a TextView widget only.
In general, a ListView is more complex having ImageView, Button or another view widgets than just a TextView is used only. This types of ListView is called "Custom ListView".
Now, I'm going to explain how to make an Android Custom ListView.

2 How to customize an Android ListView.

The item of ListView is organized as follows.
item's layout of the Custom ListView

2.1 Workflow

Worlflow for the Custom ListView Example.

2.2 Add ListView to Activity.

Declare "<ListView>" to "activity_main.xml"(or "content_main.xml") that is layout resource XML file of MainActivity.
[STEP-1] "activity_main.xml" - Declare "<ListView>"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.recipes4dev.customlistviewexample.MainActivity"
    tools:showIn="@layout/activity_main">

    <ListView
        android:id="@+id/listview1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

2.3 Configure ListView item's layout.

I didn't make item's layout in the previous article [Android ListView. (How to use Android ListView)] since the item had a TextView only. For the item with only a TextView, "simple_list_item_1" is sufficient to use. ("simple_list_item_1" is a built-in XML layout that is defined in the Android SDK. It has only one TextView and can be refered as "android.R.layout.simple_list_item_1" in your java codes.)
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, LIST_MENU) ;
Adapter and simple_list_item_1

However, for the Custom ListView, item's layout has to be added and configured.
So, I'll add ListView item's layout XML as "/res/layout/listview_item.xml" and write as follows.
[STEP-2] "/res/layout/listview_item.xml" - Configure ListView item's layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/imageView1"
        android:layout_weight="1" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="4">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/textView1"
            android:textSize="24dp"
            android:textColor="#000000"
            android:gravity="center_vertical"
            android:layout_weight="2" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/textView2"
            android:textSize="16dp"
            android:textColor="#666666"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>

2.4 Define class for ListView item.

Define class having 2 String and 1 Drawable for ListView item data.
[STEP-3] "ListViewItem.java" - Define class for ListView item.
import android.graphics.drawable.Drawable;

public class ListViewItem {
    private Drawable iconDrawable ;
    private String titleStr ;
    private String descStr ;

    public void setIcon(Drawable icon) {
        iconDrawable = icon ;
    }
    public void setTitle(String title) {
        titleStr = title ;
    }
    public void setDesc(String desc) {
        descStr = desc ;
    }

    public Drawable getIcon() {
        return this.iconDrawable ;
    }
    public String getTitle() {
        return this.titleStr ;
    }
    public String getDesc() {
        return this.descStr ;
    }
}

2.5 Implement custom adapter.

You wrote a layout resource XML for ListView item's view.
You defined a class for ListView item's data.
Now, what you have to do is to implement custom adapter by extending "BaseAdapter".
[STEP-4] "ListViewAdapter.java" - Implement custom adapter.
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class ListViewAdapter extends BaseAdapter {
    // ArrayList for saving user data.
    private ArrayList<ListViewItem> listViewItemList = new ArrayList<ListViewItem>() ;

    public ListViewAdapter() {

    }

    // mandatory : return item count in the data set.
    @Override
    public int getCount() {
        return listViewItemList.size() ;
    }

    // mandatory : return item view that displays the data.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;
        final Context context = parent.getContext();

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.listview_item, parent, false);
        }

        ImageView iconImageView = (ImageView) convertView.findViewById(R.id.imageView1) ;
        TextView titleTextView = (TextView) convertView.findViewById(R.id.textView1) ;
        TextView descTextView = (TextView) convertView.findViewById(R.id.textView2) ;

        ListViewItem listViewItem = listViewItemList.get(position);

        iconImageView.setImageDrawable(listViewItem.getIcon());
        titleTextView.setText(listViewItem.getTitle());
        descTextView.setText(listViewItem.getDesc());

        return convertView;
    }

    // mandatory : return the row id associated with the specified position.
    @Override
    public long getItemId(int position) {
        return position ;
    }

    // mandatory : return the data item associated with the specified position.
    @Override
    public Object getItem(int position) {
        return listViewItemList.get(position) ;
    }

    // convenient : add the data for a item to list.
    public void addItem(Drawable icon, String title, String desc) {
        ListViewItem item = new ListViewItem();

        item.setIcon(icon);
        item.setTitle(title);
        item.setDesc(desc);

        listViewItemList.add(item);
    }
}

2.6 add image files(png, jpg) to project.

Copy image files to the project. ("/res/drawable")
Copy image files to project.

Image files can be refered as "R.drawable.XXX" in a java code. (ex, "R.drawable.ic_account_box_black_36dp")

2.7 Create an adapter and set it to ListView.

Finally, you have to create an adapter and set it to the ListView.
[STEP-5] "MainActivity.java" - Create a adapter and set it to ListView.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listview ;
        ListViewAdapter adapter;

        // create adapter
        adapter = new ListViewAdapter() ;

        // get listview handle.
        listview = (ListView) findViewById(R.id.listview1);
        listview.setAdapter(adapter);

        // add the 1st item.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.ic_account_box_black_36dp),
                "Box", "Account Box Black 36dp") ;
        // add the 2nd item.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.ic_account_circle_black_36dp),
                "Circle", "Account Circle Black 36dp") ;
        // add the 3rd item.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.ic_assignment_ind_black_36dp),
                "Ind", "Assignment Ind Black 36dp") ;
    }

2.8 Handle the click event.

Handle the click event if you need.
[STEP-6] "MainActivity.java" - Handle a click event.
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // create OnItemClickListener and set it to ListView.
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View v, int position, long id) {
                // get item
                ListViewItem item = (ListViewItem) parent.getItemAtPosition(position) ;

                String titleStr = item.getTitle() ;
                String descStr = item.getDesc() ;
                Drawable iconDrawable = item.getIcon() ;

                // TODO : use item data.
            }
        }) ;
    }

2.9 Build and run.

Build and run "app".

3. Android Custom ListView Screenshot 

Android Custom ListView Screenshot

4. References.

.END.

No comments:

Post a Comment