Панель действий поиска не работает с классом AsyncTask

Я создал значок поиска на панели действий. Я пытался использовать Strings Array, это сработало хорошо. Но когда я попытался получить данные с веб-сервера. Поиск плохо работает. Хотя я пытался это исправить. Но это все еще не работает. Вот мой класс:

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

Вот мой AsyncTask. Я использовал его как частный класс внутри моей 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();
    }
 }

 }

Приложение работает и ошибок не выдает. Когда я пытаюсь искать. он не ищет

Вот мой адаптер

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

}

person ama989    schedule 26.11.2017    source источник
comment
опубликуйте свой ContactViewAdapter   -  person Munir    schedule 26.11.2017
comment
Мунир, я добавил свой адаптер   -  person ama989    schedule 26.11.2017
comment
Смотрите мой ответ, что вы делаете неправильно   -  person Munir    schedule 26.11.2017


Ответы (1)


Фильтр не работает, потому что вы используете пользовательский объект. Если вы передаете значение String или int адаптеру массива, он знает, как его отфильтровать. Но если вы передаете реализацию фильтра по умолчанию для настраиваемого объекта, вы не знаете, как с этим справиться. использовать собственный адаптер вместо адаптера массива

Что вам нужно сделать

  1. Расширяет BaseAdapter вместо ArrayAdater
  2. Сделать пользовательский фильтр в адаптере 3.Вернуть результат фильтра

    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
     public Filter getFilter() {
        return myFilter;
    }

Обновленный измените свой код на приведенный ниже код

Contacts_ListView nameList = originalList.get(i);
                if(nameList.getContactName().toString().contains(constraint))
                    filteredItems.add(nameList);
person Munir    schedule 26.11.2017
comment
поэтому я должен расширить свой адаптер, чтобы он расширял BaseAdapter - person ama989; 26.11.2017
comment
@ ama989 ama989 да, потому что вы хотите использовать пользовательский объект для фильтра, так как адаптер массива помогает только при строковом или целочисленном объекте - person Munir; 26.11.2017
comment
Привет @Munir, я пытался починить адаптер. Я не мог. Можете ли вы помочь мне с дополнительными объяснениями? - person ama989; 28.11.2017
comment
Я только что сделал. Пожалуйста, проверьте это. - person ama989; 29.11.2017
comment
@ ama989 смотри мой обновленный ответ, попробуй. вам нужно сравнить имя, а не весь объект. - person Munir; 29.11.2017