Search code examples
androidandroid-actionbarandroid-search

Search Action Bar is not working with AsyncTask Class


I have created a Search Icon in my Action Bar. I tried to use Strings Array, it worked well. But, when I tried to get data from a web server. The search is not working well. Though I have tried to fixed it. But, it still doesn't work. Here is my class :

public class MainActivity extends AppCompatActivity {

private String URL=
        "TTTTTTTTTT.php";
private String Contact_NAME[] ;

private JSONParser jsonParser = new JSONParser();
private ListView mListView;
private my_Adapter ContactViewAdapter;
private ArrayList<Contacts_ListView> ContactView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     mListView = (ListView)findViewById(R.id.listViewCountry);

    new Get_Contacts().execute();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_search, menu);
    MenuItem item = menu.findItem(R.id.menuSearch);
    SearchView searchView = (SearchView)item.getActionView();

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            ContactViewAdapter.getFilter().filter(newText);

            return false;
        }
    });
    return super.onCreateOptionsMenu(menu);
}

Here is my AsyncTask. I used it as a private class inside my MainActivity

private class Get_Contacts extends AsyncTask<Void, Void, Boolean>
{
    private ProgressDialog mProgressDialog;

    private JSONObject jsonObjectResult = null;
    private String error;
    private String THE_URL ;

    public Get_Contacts(){
        THE_URL = Contact_URL ;
        WITH_INPUT = false ;
    } ;
    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        ContactView = new ArrayList<Contacts_ListView>();
    }
    @Override
    protected Boolean doInBackground(Void... params)
    {
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            pairs = null;       
        jsonObjectResult = jsonParser.makeHttpRequest(THE_URL, pairs);

        if (jsonObjectResult == null)
        {
            error = "ERROR";
            return false;
        }

        try
        {
            if (jsonObjectResult.getInt("success") == 1)
            {
                JSONArray jsonArray = jsonObjectResult.getJSONArray("posts");
                saving_loop =  jsonArray.length() ;

                JSONObject news ;

                for (int i = 0; i < jsonArray.length(); i++)
                {
                    news = jsonArray.getJSONObject(i);
                    Contacts_ListView listviewcontacts  = new Contacts_ListView
                            (
                                    news.getString("Contact_Name")
                            );
                    ContactView.add(listviewcontacts);

                }
                return true;
            }
            else
                error = jsonObjectResult.getString("message");

        }
        catch (Exception ex)
        {

        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean)
    {
        super.onPostExecute(aBoolean);
        if (aBoolean)
        {
            ContactViewAdapter = new Contacts_ListViewAdapter_No_Checkbox(MainActivity.this,
                    ContactView);
            mListView.setAdapter(ContactViewAdapter);
        }
        else
            Toast.makeText(MainActivity.this, error, Toast.LENGTH_LONG).show();
    }
 }

 }

The application works and it doesn't give me any errors. When I try to search. It doesn't search

Here is my Adapter

public class Contacts_ListViewAdapter_No_Checkbox extends BaseAdapter   {
private Context mContext;
private List<Contacts_ListView> mData;
private MyFilter filter ;
private ArrayList<Contacts_ListView> originalList ;


public Contacts_ListViewAdapter_No_Checkbox (Context mContext, ArrayList<Contacts_ListView> mData) {
    //super(mContext, R.layout.contacts_shape_nocheckbox, mData);
    this.mContext = mContext;
    this.mData = mData;

    this.originalList = new ArrayList<Contacts_ListView>();
    this.originalList.addAll(mData);
}

@Override
public int getCount() {
    return mData.size();
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public Object getItem(int position) {
    return mData.get(position);
}


@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
    if (convertView == null)
    {
        LayoutInflater mInflater = (LayoutInflater)
                mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        convertView = mInflater.inflate(R.layout.contacts_shape_nocheckbox, null);
    }

    TextView Contact_Name = (TextView) convertView.findViewById(R.id.Contact_Name_1);
    Contact_Name.setText(mData.get(position).getContactName());

    return convertView;
}

public Filter getFilter() {
    if (filter == null){
        filter  = new MyFilter();
    }
    return filter;
}
private class MyFilter extends Filter
{

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        constraint = constraint.toString();
        FilterResults result = new FilterResults();
        if(constraint != null && constraint.toString().length() > 0)
        {
            ArrayList<Contacts_ListView> filteredItems = new ArrayList<Contacts_ListView>();

            for(int i = 0, l = originalList.size(); i < l; i++)
            {
                Contacts_ListView nameList = originalList.get(i);
                if(nameList.toString().contains(constraint))
                    filteredItems.add(nameList);
            }
            result.count = filteredItems.size();
            result.values = filteredItems;
        }
        else
        {
            synchronized(this)
            {
                result.values = originalList;
                result.count = originalList.size();
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence contraint, FilterResults results)  {
        mData = (ArrayList<Contacts_ListView>) results.values;
        if (results.count > 0) {
            notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }
    }
}

}

Solution

  • Filter not work because you are using a custom object. If you pass a String or int value to array adapter its know how to filter it. But if you pass custom object default filter implementation have to no idea how to deal with that. use custom adapter instead of arrayadapter

    What you need to do

    1. Extends BaseAdapter insted of ArrayAdater
    2. Make custom Filter in Adapter 3.Return filter result

      Filter myFilter = new Filter() {
      @Override
      protected FilterResults performFiltering(CharSequence constraint) {
       FilterResults filterResults = new FilterResults();   
       ArrayList<Contacts_ListView> tempList=new ArrayList<Contacts_ListView>();
       //constraint is the result from text you want to filter against. 
       //objects is your data set you will filter from
       if(constraint != null && objects!=null) {
           int length=objects.size();
           int i=0;
              while(i<length){
                  Contacts_ListView item=objects.get(i);
                  //do whatever you wanna do here
                  //adding result set output array     
      
                  tempList.add(item);
      
                  i++;
              }
              //following two lines is very important
              //as publish result can only take FilterResults objects
              filterResults.values = tempList;
              filterResults.count = tempList.size();
        }
        return filterResults;
        }
      
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence contraint, FilterResults results)  {
        objects = (ArrayList<Contacts_ListView>) results.values;
        if (results.count > 0) {
         notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }  
        }
        };
      

    Override method

    @Override
         public Filter getFilter() {
            return myFilter;
        }
    

    Updated change your code to below code

    Contacts_ListView nameList = originalList.get(i);
                    if(nameList.getContactName().toString().contains(constraint))
                        filteredItems.add(nameList);