android – search listview?-ThrowExceptions

Exception or error:

Is it possible with Android to have a search bar for a ListView so that when the search bar is touched a keyboard pops up, and when text is typed into the search bar, the items that match in the ListView are shown?

What I really need is the search bar that brings up a keyboard.

Update:

I’ve added the EditText field that brings up a keyboard and I can type into the EditText field. What I want is to have the first few characters of the items in the list shown in the ListView match the characters typed into the EditText window.

I’ve tried following the approach listed here ListView Filter but I am a little confused as to how much filtering is already done in ListView?

1) Do I need to create a separate array that stores the values that match the text typed into EditText? From this post Call adapter.notifyDataSetChanged, it appears that ListView already has a shadow array to do this, and it gets updated when adapter.notifyDataSetChanged(); is called.

2) Do I need to call adapter.notifyDataSetChanged(); to have ListView updated after I type some text in the EditText window?

3) Do I need to extend ListActivity as this post indicates? If so how do I extend my activity class if the activity class is already being extended from the main activity?

4) What I currently have is the following:

ArrayAdapter<String> adapter = null;
private EditText filterText = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.symptom);
    ListView symptomList = (ListView) findViewById(R.id.ListView_Symptom);
    symptomList.setTextFilterEnabled(true);
    symptomList.setFastScrollEnabled(true);
    filterText = (EditText) findViewById(R.id.search_box);
    filterText.addTextChangedListener(filterTextWatcher);

    adapter = new ArrayAdapter<String>(this, R.layout.menu_item, symptomsArray);
    symptomList.setAdapter(adapter);

    private TextWatcher filterTextWatcher = new TextWatcher() {

        public void afterTextChanged(Editable s) {
        }

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

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            adapter.getFilter().filter(s);
            adapter.notifyDataSetChanged();
        }

    };

Unfortunately at the moment when I type in the EditText box, I get a NullPointer Exception in

 Thread [<7> Filter] (Suspended (exception NullPointerException))   
ArrayAdapter$ArrayFilter.performFiltering(CharSequence) line: 437   
Filter$RequestHandler.handleMessage(Message) line: 234  
Filter$RequestHandler(Handler).dispatchMessage(Message) line: 99    
Looper.loop() line: 123 
HandlerThread.run() line: 60    

Any idea what I am missing?

How to solve:

You have done very small mistake :- create array adapter before setting text changed Listener to the edit text

see the corrected code

public class SearchListView extends Activity
{


/** Called when the activity is first created. */

private ListView lv1;
private String lv_arr[] =
{ "Android", "iPhone", "BlackBerry", "me", "J2ME", "Listview", "ArrayAdapter", "ListItem", "Us", "UK", "India" };
ListView lst;
EditText edt;
ArrayAdapter<String> arrad;



@Override
public void onCreate( Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    lv1=(ListView)findViewById(R.id.ListView01);
    edt = (EditText) findViewById(R.id.EditText01);

     arrad =  new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , lv_arr);
     lv1.setAdapter(arrad);

    // By using setTextFilterEnabled method in listview we can filter the listview items.

     lv1.setTextFilterEnabled(true);
     edt.addTextChangedListener(new TextWatcher()
    {


        @Override
        public void onTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
        {
            // TODO Auto-generated method stub

        }



        @Override
        public void beforeTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
        {
            // TODO Auto-generated method stub

        }



        @Override
        public void afterTextChanged( Editable arg0)
        {
            // TODO Auto-generated method stub
            SearchListView.this.arrad.getFilter().filter(arg0);

        }
    });

}

}

###

If you implement Filterable in your adapter, ListView can handle the filtering.

###

As yet another approach, the ListView itself can show the text that the user is entering (as opposed to using a separate TextView) by handling the onKeyUp events, scrolling the ListView to the item that has the entered text, and underlining that text in the ListView. I use AsyncTask to implement the ListView text search and that results in a convenient type ahead capability.

###

This page has working example of what you are looking for
http://learningsolo.com/android-text-search-filter-with-textwatcher-in-listview-example/

Add search box in app bar layout:

<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay">

<!-- To add Search Text box to action bar -->
        <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay">
            <EditText android:layout_width="200dp" android:layout_height="wrap_content" android:id="@+id/searchProjectTxt" android:layout_marginLeft="30dp" android:singleLine="true" android:hint="Search Here..." />
        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>

Then add TextWatcher on “searchProjectTxt” to add filter

EditText searchTxt = (EditText)findViewById(R.id.searchProjectTxt);
searchTxt.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                filter(cs.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                          int arg3) {
            }

            @Override
            public void afterTextChanged(Editable arg0) {
            }
        });
    }

    void filter(String text){
        List<ProjectsVo> temp = new ArrayList();
        for(ProjectsVo d: projectListCache){
            if(d.getTitle().toLowerCase().contains(text.toLowerCase())){
                temp.add(d);
            }
        }
        projectList.clear();
        projectList.addAll(temp);
        adapter.notifyDataSetChanged();
    }

Leave a Reply

Your email address will not be published. Required fields are marked *