0

I have a ListView that works well by itself, but for some reason adding a search bar seems to ruin everything. I can open the ListView and click on an item to get to a new page, but pressing a key to type in the searchbar results in "Unfortunately, myapp has stopped". I'm getting a NullPointerException from the logcat but nothing I do seems to fix it. Any help would be much appreciated!

The listview activity:

public class SecondScreenActivity extends Activity
{

    // Listview Adapter
    ArrayAdapter<String> arrayAdapter;

    // Search EditText
    EditText inputSearch;

        ArrayList<String> RecipeList;
        public void onCreate(Bundle saveInstanceState)
        {
                super.onCreate(saveInstanceState);
                setContentView(R.layout.main);

               // Get the reference of ListViewRecipes
                ListView RecipeListView=(ListView)findViewById(R.id.mainListView);

                 RecipeList = new ArrayList<String>();
                 getRecipeNames();

                 RecipeListView = (ListView) findViewById(R.id.mainListView);
                 inputSearch = (EditText) findViewById(R.id.inputSearch);

                 // Adding items to listview
                 ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, RecipeList); 
     //^^^this is the line that seems to be the problem^^^

                 // Set The Adapter
                 RecipeListView.setAdapter(arrayAdapter);


                 //Search
                 inputSearch = (EditText) findViewById(R.id.inputSearch);
                 /**
                  * Enabling Search Filter
                  * */
                 inputSearch.addTextChangedListener(new TextWatcher() {

       @Override
       public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
       // When user changes the Text
       SecondScreenActivity.this.arrayAdapter.getFilter().filter(cs);   
       }

       @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                          
       }
       });

       // register onClickListener to handle click events on each item
       RecipeListView.setOnItemClickListener(new OnItemClickListener()
       {
           public void onItemClick(AdapterView<?> parent, View itemClicked,
                            int position, long id) {

           TextView textView = (TextView) itemClicked;
           String strText = textView.getText().toString();

           Intent intenttwo = new Intent(SecondScreenActivity.this, ThirdScreenActivity.class);
           intenttwo.putExtra("position", strText);
           startActivity(intenttwo);
           }
           });

        }

        void getRecipeNames()
        {
            RecipeList.add("Recipe1");
            RecipeList.add("Recipe2");
            RecipeList.add("Recipe3");
            RecipeList.add("Recipe4");
            RecipeList.add("Recipe5");
            RecipeList.add("Recipe6");
            RecipeList.add("Recipe7");
            RecipeList.add("Recipe8");
            RecipeList.add("Recipe9");
            RecipeList.add("Recipe10");

        }  
}

EDIT: This is a slightly modified listview activity. This makes the searchbar work, however when clicking the items in the ListView the app is forced to close, with the logcat error: java.lang.classcastexception: android.widget.linearlayout cannot be cast to android.widget.textview. This might help, it might not!

import java.util.ArrayList;
import java.util.HashMap;    
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;

public class SecondScreenActivity extends Activity
{
    // List view
    private ListView lv;

    // Listview Adapter
    ArrayAdapter<String> adapter;

    // Search EditText
    EditText inputSearch;


    // ArrayList for Listview
    ArrayList<HashMap<String, String>> recipeList;

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

        // Listview Data
        String recipes[] = {"Recipe1", "Recipe2", "Recipe3", "Recipe4", "Recipe5",
                             "Recipe6", "Recipe7", "Recipe8", "Recipe9", "Recipe10"};

        lv = (ListView) findViewById(R.id.mainListView);
        inputSearch = (EditText) findViewById(R.id.inputSearch);

        // Adding items to listview
        adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.recipe_name, recipes);
        lv.setAdapter(adapter);

        // Enabling search filter
        inputSearch.addTextChangedListener(new TextWatcher() {

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

            @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                          
            }
        });

     // register onClickListener to handle click events on each item
        lv.setOnItemClickListener(new OnItemClickListener()
           {


                    // argument position gives the index of item which is clicked
                public void onItemClick(AdapterView<?> parent, View itemClicked,
                int position, long id) {                

                    //TO DO: Send string (position) of recipe name

//                  TextView textView = (TextView) findViewById(itemClicked);
//                  String stringName = textView.getText().toString();
                    String stringName = (String) (lv.getItemAtPosition(position));

            Intent intenttwo = new Intent(SecondScreenActivity.this, ThirdScreenActivity.class);
            intenttwo.putExtra("position", stringName);
            startActivity(intenttwo);
        }
        });
    }
}

And my logcat (when using the first activity):

06-25 22:37:54.353: E/AndroidRuntime(4646): FATAL EXCEPTION: main
06-25 22:37:54.353: E/AndroidRuntime(4646): java.lang.NullPointerException
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.example.myapp.SecondScreenActivity$1.onTextChanged(SecondScreenActivity.java:66)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.widget.TextView.sendOnTextChanged(TextView.java:7231)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.widget.TextView.handleTextChanged(TextView.java:7290)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:8880)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:435)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:30)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:222)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:136)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.widget.TextView.doKeyDown(TextView.java:5385)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.widget.TextView.onKeyDown(TextView.java:5204)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.KeyEvent.dispatch(KeyEvent.java:2609)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.View.dispatchKeyEvent(View.java:7205)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1359)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1920)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1395)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.app.Activity.dispatchKeyEvent(Activity.java:2370)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1847)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3701)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3651)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2818)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.os.Looper.loop(Looper.java:137)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at android.app.ActivityThread.main(ActivityThread.java:5041)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at java.lang.reflect.Method.invokeNative(Native Method)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at java.lang.reflect.Method.invoke(Method.java:511)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-25 22:37:54.353: E/AndroidRuntime(4646):     at dalvik.system.NativeStart.main(Native Method)

Thanks for the help!

stackUnderflow
  • 149
  • 2
  • 8

1 Answers1

0

This answer should help you, it has a good example. I believe you need to override the getFilter() method in your adapter if you are using a Custom Adapter which it doesn't look like you are.

In that case, you can use setOnQueryTextListener and implement it something like

searchField = (SearchView) findViewById(R.id.search_plate);
    searchField.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            // search goes here !!
            setFilters("searchtext", newText);

            return false;
        }
    });

where setFilters() is a function defined by you. This is an example of how mine is so your variables and such will be a little different.

You may also find this answer and this one useful. I hope this helps

SearchView Docs

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • I'll try and fit that code in, but I'm not exactly sure where it goes/what it replaces. The weird thing is, my SearchView does actually work if I convert my listview to a hashmap format, but then the ListView won't click to the next activity! – stackUnderflow Jun 26 '13 at 11:19
  • sorry for loads of comments, but i've edited my question, it might help. – stackUnderflow Jun 26 '13 at 11:39
  • No problem. Well, if that's the case then can you create a separate `HashMap` to use for searching without changing your `ListView`? – codeMagic Jun 26 '13 at 13:31
  • Um, I'm not too sure what you mean. Could you give me some example code? – stackUnderflow Jun 26 '13 at 15:32
  • In your edited example, is `recipe_name` the `id` of a `LinearLayout`? – codeMagic Jun 26 '13 at 15:45
  • I didn't realise LinearLayouts had ids, but no, it's only the id of the single list item TextView – stackUnderflow Jun 26 '13 at 17:19
  • Yes, you can give an `id` to a `ViewGroup`. If you're getting a class cast exception where you aren't trying to cast then cleaning your project may help. Otherwise, let me know what line you get that exception. Sorry, I'm a little confused on what's going on in your code right now – codeMagic Jun 26 '13 at 17:23
  • I have no idea what's going on, but I cleaned it and it's working now, I'd cleaned it hundreds of times before and deleted r.java etc so I have no idea why it worked this time! I'll try and see what the cleaning did, and let you know if it helps. Anyway, I'll give you the answer, so thanks very very much, I'd been stuck on that for weeks! – stackUnderflow Jun 26 '13 at 17:43
  • You're welcome. Sometimes Eclipse doesn't detect some changes so when you get a goofy error like that cleaning is usually the first and simplest thing to do. – codeMagic Jun 26 '13 at 17:49
  • The weird thing is I've cleaned it many times before! Not complaining though, it works! – stackUnderflow Jun 26 '13 at 17:52