Search code examples
androidlistviewandroid-listviewandroid-edittextandroid-search

Search Filter in the ListView Not Working as Expected


We have a list view fragment that contains a listview, edit text(for search) and check box(Select All). As mentioned we are using Edit Text for searching the values from the list view.

Problem:

  1. We have list view displaying 10 items( list view sorted alphabetically).
  2. When we type 'W' in the edit text we are displayed with two values i.e. WF and WH.
  3. The selection is made for WF(first item displayed).
  4. After clearing the characters in the edit text, we are now displayed with the complete list of the list view.
  5. But the selection is now made for first item in the list AHMD. (we intended to select WF)

Basically, the positions of the data in the list view is not getting refreshed after we have performed search.

code:

 public static class ListViewFragment extends Fragment {

    private ListView myListView;
    private EditText editsearch;
    private CheckBox selectAll;
    private String SELECTED_FILTER;
    private ArrayList<String> SelectedFilter1;
    private ArrayList<String> checkekprev=new ArrayList<String>();
    private ArrayList<String> CheckedFitlers=new ArrayList<String>();

    ArrayAdapter<String> adapter_list;

    OnCheckedItemsLister onCheckedItemsLister;     

    public ListViewFragment() {
        // Empty constructor required for fragment subclasses
    }

    @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
          try {
              onCheckedItemsLister = (OnCheckedItemsLister) activity;
          } catch (ClassCastException e) {
              throw new ClassCastException(activity.toString() + " must implement onSomeEventListener");
          }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);  
        setRetainInstance(true);
        SelectedFilter1=getArguments().getStringArrayList("ArrayList");
        SELECTED_FILTER=getArguments().getString("SELECTED_FILTER");
        checkekprev=getArguments().getStringArrayList("checkedprevlist");




        if(checkekprev.size()==SelectedFilter1.size())
            selectAll.setChecked(true);
            else
            selectAll.setChecked(false);

        adapter_list = new ArrayAdapter<String>(this.getActivity(),
                android.R.layout.simple_list_item_multiple_choice,SelectedFilter1);

        adapter_list.notifyDataSetChanged();

        myListView.setAdapter(adapter_list);

        myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

        myListView.setTextFilterEnabled(true);

        try{
            if(checkekprev.isEmpty()==false){
                Log.i("Adapter set", "Yes");
                for(int j=0;j<checkekprev.size();j++){
                    Log.i("Adapter set", "Yes:"+j);
                int pos=adapter_list.getPosition(checkekprev.get(j));
                Log.i("Adapter set", "Pos:"+pos);
                myListView.setItemChecked(pos,true);
                }

            }           
        }catch(NullPointerException  e){
            Log.i("Null set", "Yes");
        }

        editsearch.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub
                String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
                adapter_list.getFilter().filter(text);
            }

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

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

        selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {

                Log.i("CheckBOX","Is Checked:"+isChecked);
                if(isChecked)
                {
                    for ( int i=0; i< myListView.getCount(); i++ ) 
                        myListView.setItemChecked(i, true);

                }else
                {
                    for ( int i=0; i< myListView.getCount(); i++ ) 
                        myListView.setItemChecked(i, false);
                }
                SparseBooleanArray checked = myListView.getCheckedItemPositions();
                CheckedFitlers.clear();
                for(int i=0;i<=checked.size();i++){
                    if (checked.get(i)){
                        CheckedFitlers.add(SelectedFilter1.get(i));
                    }
                }
                onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER);
            }
        }
     );

        myListView.setOnItemClickListener(new OnItemClickListener() { 

            public void onItemClick(AdapterView<?> parent, View view,int position, long id){
                setItemChecked(position);
                onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER); 

            }               
        });

    }

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

        if(savedInstanceState!=null){
            checkekprev=savedInstanceState.getStringArrayList("Checked_Values");
        }
    }

    public void setItemChecked(int position){

        //if(SelectedFilter1.get(position).)

            //int len = myListView.getCount();
            SparseBooleanArray checked = myListView.getCheckedItemPositions();

            for(int i=0;i<=checked.size();i++){
                Log.i("Check Sparse Array","Check Sparse Array: "+checked.get(i));
            }

            //for (int i = 0; i < len; i++){
                Log.i("SelectedFilter1.get(position)","SelectedFilter1.get(position):::"+SelectedFilter1.get(position));

                Log.i("checked.get(position))","checked.get(position)):::"+checked.get(position));

                for (int i=0; i<CheckedFitlers.size();i++){
                    Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.get(i));
                }
                for (int i=0; i<checkekprev.size();i++){
                    Log.i("checkekprev","checkekprev:::" + checkekprev.get(i));
                }
                Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());
                Log.i("checkekprev","checkekprev:::" + checkekprev.size());

                if(CheckedFitlers.size() == 0 && checkekprev.size() != 0){
                    CheckedFitlers = checkekprev;
                }

                Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());

                if (checked.get(position)) {
                    Log.i("Adding","Adding::"+checked.get(position));

                    CheckedFitlers.add(SelectedFilter1.get(position));
                 for(int i=0;i<checkekprev.size();i++){
                        //Log.i("Checked Filters FOr loop","Checked Filters:"+CheckedFitlers.get(i));
                    }
               }    else
               {
                Log.i("Removing","Removing::"+checked.get(position)+":"+SelectedFilter1.get(position));
                CheckedFitlers.remove(SelectedFilter1.get(position));
                    for(int i=0;i<checkekprev.size();i++){
                        //Log.i("Checked Filters for loop","Checked Filters:"+CheckedFitlers.get(i));
                    }
               }
                Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());

    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {        

        View rootView = inflater.inflate(R.layout.fragment_list_view, container, false);

        myListView=(ListView) rootView.findViewById(R.id.listView_brand);

        editsearch = (EditText) rootView.findViewById(R.id.search);

        selectAll=(CheckBox) rootView.findViewById(R.id.checkBox1);

        selectAll.setFocusable(false);

        return rootView;
    }

    public void onSaveInstanceState(Bundle savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);

        Log.i("savedInstanceState in listfragment","savedInstanceState in listfragment");
        //onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER);
        onCheckedItemsLister.getSelectedFilter(SELECTED_FILTER);

    }

}

Solution

  • When you typed 'W' in the edit text we are displayed with two values i.e. WF and WH. The selection is made for WF(first item displayed).

    But you have performed action for first row of a listview, Now the checkbox of listview is checked and when clearing the characters in the edit text, your are seeing the complete list of the list view with first box checked. which is correct.

    If you want to avoid this issues, Create custom adapter and override getfilter method.

    Otherwise, Create your own logic and call listView.setItemChecked( stored positions, true/false); in ontextchanged.