Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an EditText to filter a SimpleCursorAdapter-backed ListView

Tags:

android

I have a ListView with a custom item layout backed by a SimpleCursorAdapter. I'd like the user to be able to type text into an EditText box and have the ListView automatically filter as they type. It looks like this is very simple to do with an ArrayAdapter, as described here.

Unfortunately, I'm not having any luck getting it working with a SimpleCursorAdapter. I've tried adding extra methods as described here, but that example is for an AutoCompleteTextView instead of a ListView. I haven't been able to get anything working for my ListView.

Can somebody provide me with an example of filtering a SimpleCursorAdapter-backed ListView with an EditText box?

public class DirectoryListActivity extends DirectoryActivity {

    private static SimpleCursorAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.directory_list);

        fillPeopleListView();

        EditText etext=(EditText)findViewById(R.id.search_box);
        etext.addTextChangedListener(new TextWatcher() {

            public void onTextChanged(CharSequence s, int start, int before, int count) {


            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {


            }

            public void afterTextChanged(Editable s) {
                adapter.getFilter().filter(s.toString());

            }
        });

    }

    private void fillPeopleListView() {
        // Populate the ListView
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(
            directoryPeople.PEOPLE_TABLE
        );

        String asColumnsToReturn[] = { 
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.LAST_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.FIRST_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.MIDDLE_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.JOB_TITLE + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople._ID
        };

        mCursor = queryBuilder.query(mDB, asColumnsToReturn, null, null,
                null, null, directoryPeople.DEFAULT_SORT_ORDER);

        startManagingCursor(mCursor);

        adapter = new SimpleCursorAdapter(this,
                R.layout.directory_people_item, mCursor,
                new String[]{
                    directoryPeople.LAST_NAME,
                    directoryPeople.FIRST_NAME,
                    directoryPeople.MIDDLE_NAME,
                    directoryPeople.JOB_TITLE},
                new int[]{
                    R.id.txtLastName,
                    R.id.txtFirstName,
                    R.id.txtMiddle,
                    R.id.txtTitle} 
        ); 

        ListView av = (ListView)findViewById(R.id.listPeople);
        av.setAdapter(adapter);
        av.setFastScrollEnabled(true);

        adapter.setFilterQueryProvider(new FilterQueryProvider() {

            public Cursor runQuery(CharSequence constraint) {
                String partialValue = constraint.toString();

                SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

                String asColumnsToReturn[] = { 
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.LAST_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.FIRST_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.MIDDLE_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.JOB_TITLE + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople._ID
                };

                Cursor c = queryBuilder.query(mDB, asColumnsToReturn, directoryPeople.LAST_NAME + " LIKE " + partialValue, null,
                        null, null, directoryPeople.DEFAULT_SORT_ORDER);


                return c;
            }
        });

}

Here's my layout code, as requested. Main layout:

<?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="vertical"
    android:background="@android:color/white">
    <include android:id="@+id/lytHeadBar" layout="@layout/headbar" />
    <include android:id="@+id/lytTitleBar" layout="@layout/titlebar" />
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Type a name..."
        android:maxLines="1" android:inputType="textFilter|textCapWords" android:id="@+id/search_box"/>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listPeople"
        android:divider="@android:drawable/divider_horizontal_dark"
        android:cacheColorHint="@android:color/white" />
</LinearLayout>

List item layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lytItem"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:background="@drawable/item_line_bottom">
    <LinearLayout android:id="@+id/nameLine"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="horizontal">
            <TextView
                android:id="@+id/txtLastName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp"
                android:textStyle="bold"
                android:textColor="@android:color/black"
                android:text="lastname" />
            <TextView
                android:id="@+id/nameSpace1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text=", " />
            <TextView
                android:id="@+id/txtFirstName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text="firstname" />
            <TextView
                android:id="@+id/nameSpace2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text=" " />
            <TextView
                android:id="@+id/txtMiddle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text="middle" />    
        </LinearLayout>
    <LinearLayout android:id="@+id/titleLine"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/txtTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:textColor="@android:color/black"
            android:text="title" android:ellipsize="marquee"/>
    </LinearLayout>
</LinearLayout>
like image 685
LouieGeetoo Avatar asked Mar 07 '11 06:03

LouieGeetoo


2 Answers

well it's much more like arrayAdapter here is sample code

public class ListViewFilter extends Activity {
private ItemDatabaseHelper itemData;
private SimpleCursorAdapter sc;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    itemData=new ItemDatabaseHelper(this);
    Cursor c=itemData.getAllValues(); 

    sc=new 
        SimpleCursorAdapter(this, R.layout.list_items, c, new String[]{itemData.VALUE}, new int[]{R.id.txtItem});
    ListView lv=(ListView)findViewById(R.id.lstItems);
    lv.setAdapter(sc);
    sc.setFilterQueryProvider(new FilterQueryProvider() {

        @Override
        public Cursor runQuery(CharSequence constraint) {
            String partialValue = constraint.toString();
            return itemData.getAllSuggestedValues(partialValue);

        }
    });
    EditText etext=(EditText)findViewById(R.id.etxtItemName);
    etext.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {


        }

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


        }

        @Override
        public void afterTextChanged(Editable s) {
            sc.getFilter().filter(s.toString());

        }
    });
}

}

and two xml files are listed below

main.xml is

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<EditText  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/etxtItemName"
    android:layout_alignParentTop="true"
    />
<ListView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/lstItems"
    android:layout_below="@+id/etxtItemName"
    />
</RelativeLayout>

and list_item.xml is

  <?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/txtItem"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
</TextView>

Hope this will help you

like image 114
Sunil Pandey Avatar answered Nov 15 '22 00:11

Sunil Pandey


Finally managed to solve the issue! Answer can be found here: ListView, SimpleCursorAdapter, an an EditText filter -- why won't it do anything?

like image 40
LouieGeetoo Avatar answered Nov 15 '22 01:11

LouieGeetoo