Android ListView Tutorial

0

About ListView

A ListView is the most often used UI and Android’s framework provides an excellent support for it from the perspective of model and view.

  • A ListView can be customized
  • We can have separate views for ListView and empty list view
  • If you want, you may also show more than one view type at each row. We may need this when you want to group your list.
  • The underneath model can vary from an ArrayAdaptor (contains array of objects) to a CursorAdaptor that renders the info stored in a database to your own adapter extending BaseAdapter.
  • A list activity extends android’s ListActivity. If it is a fragment it has to extend ListFragment.
In our previous articles, I showed you how to create a ListView Layout and an Add action bar at the bottom of the list where you can an enter an item and add. I also showed how we can show a different view when the list is empty.

In this article, I will show you how you can add items. You will see the list activity, how we set the list adapter (the model) and the listeners which add the text keyed in to the list. Initially the list will be empty.

 

Moment you type in, the hidden ‘+’ button shows up on the extreme left of Add field.

 

ListView layout

You will have to provide a layout for the empty view with id="@[email protected]/empty" and a ListView with id="@android:id/list". Note that these ids are android specific ones and it needs them to manage the ListView so you shouldn’t use some other ids.

Simple Layout

Here the empty view will just have a text like ‘You don’t have items in List…’.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/taskListParent"
              android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">

    <TextView android:id="@android:id/empty" android:layout_width="fill_parent" android:layout_height="0dp"
              android:text="@string/no_items" android:layout_weight="1" android:gravity="center"/>

    <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dp"
              android:layout_weight="1"/>

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
                  android:orientation="horizontal">

        <EditText android:id="@+id/quickAddText" android:layout_width="0dp" android:layout_height="wrap_content"
                  android:hint="@string/add_hint" android:layout_weight="1"/>

        <ImageButton android:id="@+id/quickAddButton" android:layout_width="wrap_content"
                     android:layout_height="wrap_content" android:contentDescription="@string/add_hint"
                     android:src="@drawable/btn_add" android:onClick="add"/>

    </LinearLayout>

</LinearLayout>

 

Layout using ViewStub

This is a similar layout except that the empty view held by ViewStub has a separate layout. This is a better coding practice as ViewStub doesn’t inflate unless the view is made visible.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/taskListParent"
              android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">

    <FrameLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1">

        <ViewStub android:id="@android:id/empty" android:layout_width="wrap_content"
                  android:layout_height="wrap_content" android:layout_gravity="center"
                  android:layout="@layout/empty_list"/>

        <ListView android:id="@android:id/list" android:layout_width="fill_parent"
                  android:layout_height="wrap_content"/>

    </FrameLayout>

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
                  android:orientation="horizontal">

        <EditText android:id="@+id/quickAddText" android:layout_width="0dp" android:layout_height="wrap_content"
                  android:layout_weight="1" android:hint="@string/add_hint"/>

        <ImageButton android:id="@+id/quickAddButton" android:layout_width="wrap_content"
                     android:layout_height="wrap_content" android:background="@android:color/transparent"
                     android:contentDescription="@string/add_hint" android:onClick="add"
                     android:src="@drawable/btn_add"/>

    </LinearLayout>

</LinearLayout>

 

ListActivity

  • Create your own ListActivity which extends android’s ListActivity.
  • Override onCreate() to configure with the listeners and the model.
  • Set the content view to the ListView layout page which we have created above.
  • Find the text field and add button components to configure the listeners.
  • Bind a model by setting up an adapter to the ListView.

What is an adapter class?

An Adapter class contains the actual model and helps us to bind it to the ListView.

  • You can create your own extending Adapter extending BaseAdapter which I will show one in my coming articles. For now, we will use the pre-built ArrayAdapter.
  • You also need to let the view know how you want to display each item in the list. The layout of the list item view can be our own or you can use the pre-built views that android provides. I have used simple list item layout (android.R.layout.simple_list_item_1) to display the item.

Next, lets configure listeners. I have used two listeners here.

  • The first one is TextWatcher, to make the + button visible as soon as user enters something in the text box.
  • The second one is OnKeyListener. When we press enter, the item typed-in must get added to the list.
  • Note that I have checked the key code and action. I want to consume the event when ENTER is pressed so other than checking Key Code, I also want to be sure about the action which is DOWN in my case. If you don’t have check on the action, you will end with two elements in the List.
public class TaskListWithAddActivity extends ListActivity {

    private ArrayAdapter _adapter;
    private TextView _itemField;
    private ImageButton _addButton;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_list_with_add_first);
        _itemField = (TextView) findViewById(R.id.quickAddText);
        _addButton = (ImageButton) findViewById(R.id.quickAddButton);
        _adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1);
        setListAdapter(_adapter);

        _itemField.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence itemText, int start,
                                      int before, int count) {
                final boolean addButtonVisible = !TextUtils.isEmpty(itemText);
                _addButton.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        _addButton
                                .setVisibility(addButtonVisible ? View.VISIBLE
                                        : View.GONE);
                    }
                }, 10);
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {/**/
            }

            @Override
            public void afterTextChanged(Editable s) {/**/
            }
        });

        _itemField.setOnKeyListener(new View.OnKeyListener() {

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if ( keyCode == KeyEvent.KEYCODE_ENTER
                        & amp;&
                (event.getAction() == KeyEvent.ACTION_DOWN)){
                    add(v);
                    return true;
                }
                return false;
            }
        });
    }

    public void add(View inView) {
        String item = _itemField.getText().toString();
        add(item);
        _itemField.setText("");
    }

    private boolean add(String item) {
        if (!TextUtils.isEmpty(item.trim())) {
            _adapter.add(item);
            return true;
        } else {
            return false;
        }
    }
}

Download Source Code

You can download the source code here: sandboxListView.zip

Share.

Leave A Reply