Implement search in ListView inside fragment

Hi guys I am trying to implement a search function in a list embedded in a Listview fragment works fine, but when I type to edittext to search it disappears

My code:

public class DrinksFragment extends Fragment {

    private View rootView;
    private ArrayAdapter<DrinksList> adapter;
    private List<DrinksList> drinks;
    private ListView lv;
    ArrayList<DrinksList> mAllData;
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.activity_drinks_fragment, container, false);
        populateDrinksList();
        doSearch();
        return rootView;
    }

    private void doSearch() {
        final EditText et = (EditText)rootView.findViewById(R.id.searchListDrinks);
        et.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                String text = et.getText().toString().toLowerCase(Locale.getDefault());
            adapter.filter(text);
            }
        });
    }



    private void populateDrinksList() {
        drinks = new ArrayList<DrinksList>();
        drinks.add(new DrinksList(R.drawable.coca, "Coca Cola", 2.50));
        drinks.add(new DrinksList(R.drawable.cocalight, "Coca Cola Light", 2.50));
        drinks.add(new DrinksList(R.drawable.cocazero, "Coca Cola Zero", 2.50));
        drinks.add(new DrinksList(R.drawable.orange, "Fanta Orange", 2.50));
        drinks.add(new DrinksList(R.drawable.lemon, "Fanta Lemon", 2.50));
        drinks.add(new DrinksList(R.drawable.ble, "Fanta Blue", 2.50));
        drinks.add(new DrinksList(R.drawable.sprite, "Sprite", 2.50));
        drinks.add(new DrinksList(R.drawable.soda, "Soda Water", 2.50));
        drinks.add(new DrinksList(R.drawable.tonic, "Tonic Water", 2.50));
        drinks.add(new DrinksList(R.drawable.ioli, "Sparkling Water Ioli", 2.50));
        drinks.add(new DrinksList(R.drawable.perrier, "Sparkling Water Perrier", 2.50));
        drinks.add(new DrinksList(R.drawable.nero, "Still Water", 2.00));
        drinks.add(new DrinksList(R.drawable.redbull, "Red Bull", 4.00));
        drinks.add(new DrinksList(R.drawable.zelita, "Zelita", 2.50));
        lv = (ListView)rootView.findViewById(R.id.drinksListView);
        adapter = new MyCustomDrinksListAdapter(getActivity().getApplicationContext(), R.layout.list_item, drinks);
        lv.setAdapter(adapter);
    }

}public class DrinksFragment extends Fragment {

    private View rootView;
    private ArrayAdapter<DrinksList> adapter;
    private List<DrinksList> drinks;
    private ListView lv;
    ArrayList<DrinksList> mAllData;
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.activity_drinks_fragment, container, false);
        populateDrinksList();
        doSearch();
        return rootView;
    }

    private void doSearch() {
        final EditText et = (EditText)rootView.findViewById(R.id.searchListDrinks);
        et.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                DrinksFragment.this.adapter.getFilter().filter(s);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }



    private void populateDrinksList() {
        drinks = new ArrayList<DrinksList>();
        drinks.add(new DrinksList(R.drawable.coca, "Coca Cola", 2.50));
        drinks.add(new DrinksList(R.drawable.cocalight, "Coca Cola Light", 2.50));
        drinks.add(new DrinksList(R.drawable.cocazero, "Coca Cola Zero", 2.50));
        drinks.add(new DrinksList(R.drawable.orange, "Fanta Orange", 2.50));
        drinks.add(new DrinksList(R.drawable.lemon, "Fanta Lemon", 2.50));
        drinks.add(new DrinksList(R.drawable.ble, "Fanta Blue", 2.50));
        drinks.add(new DrinksList(R.drawable.sprite, "Sprite", 2.50));
        drinks.add(new DrinksList(R.drawable.soda, "Soda Water", 2.50));
        drinks.add(new DrinksList(R.drawable.tonic, "Tonic Water", 2.50));
        drinks.add(new DrinksList(R.drawable.ioli, "Sparkling Water Ioli", 2.50));
        drinks.add(new DrinksList(R.drawable.perrier, "Sparkling Water Perrier", 2.50));
        drinks.add(new DrinksList(R.drawable.nero, "Still Water", 2.00));
        drinks.add(new DrinksList(R.drawable.redbull, "Red Bull", 4.00));
        drinks.add(new DrinksList(R.drawable.zelita, "Zelita", 2.50));
        lv = (ListView)rootView.findViewById(R.id.drinksListView);
        adapter = new MyCustomDrinksListAdapter(getActivity().getApplicationContext(), R.layout.list_item, drinks);
        lv.setAdapter(adapter);
    }

}

      

My adapter:

public class MyCustomDrinksListAdapter extends ArrayAdapter<DrinksList> {


    private List<DrinksList> items = null;
    private ArrayList<DrinksList> arraylist;
    public MyCustomDrinksListAdapter(Context context, int layoutId, List<DrinksList> items) {
        super(context, layoutId, items);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View arrayView = convertView;
        if(arrayView == null){
            LayoutInflater vi;
            vi = LayoutInflater.from(getContext());
            arrayView = vi.inflate(R.layout.list_item, parent, false);
        }

        DrinksList currentPosition = getItem(position);
        if(currentPosition != null){
            ImageView image = (ImageView)arrayView.findViewById(R.id.product_image_coffee);
            image.setImageResource(currentPosition.getImage());

            TextView name = (TextView)arrayView.findViewById(R.id.product_name_coffee);
            name.setText(currentPosition.getName());

            TextView price = (TextView)arrayView.findViewById(R.id.product_price_coffee);
            price.setText(String.format("%.2f", currentPosition.getPrice()));
        }
        return arrayView;
    }

    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        items.clear();
        if (charText.length() == 0) {
            items.addAll(arraylist);
        } else {
            for (DrinksList wp : arraylist) {
                if (wp.getName().toLowerCase(Locale.getDefault())
                        .contains(charText)) {
                    items.add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }
}

      

I tried following the example of android developers, but I couldn't. Thank you in advance!! any ideas?

+3


source to share


4 answers


Instead of adding a filter method to the adapter class ... add it to the snippet .. like this ..

    public class DrinksFragment extends Fragment {

    private View rootView;
    private ArrayAdapter<DrinksList> adapter;
    private List<DrinksList> drinks;
    private ListView lv;
    ArrayList<DrinksList> mAllData=new ArrayList<DrinksList>();
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.activity_drinks_fragment, container, false);
        populateDrinksList();
        doSearch();
        return rootView;
    }

    private void doSearch() {
        final EditText et = (EditText)rootView.findViewById(R.id.searchListDrinks);
        et.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                String text = et.getText().toString().toLowerCase(Locale.getDefault());
            filter(text);
            }
        });
    }



    private void populateDrinksList() {
        drinks = new ArrayList<DrinksList>();
        drinks.add(new DrinksList(R.drawable.coca, "Coca Cola", 2.50));
        drinks.add(new DrinksList(R.drawable.cocalight, "Coca Cola Light", 2.50));
        drinks.add(new DrinksList(R.drawable.cocazero, "Coca Cola Zero", 2.50));
        drinks.add(new DrinksList(R.drawable.orange, "Fanta Orange", 2.50));
        drinks.add(new DrinksList(R.drawable.lemon, "Fanta Lemon", 2.50));
        drinks.add(new DrinksList(R.drawable.ble, "Fanta Blue", 2.50));
        drinks.add(new DrinksList(R.drawable.sprite, "Sprite", 2.50));
        drinks.add(new DrinksList(R.drawable.soda, "Soda Water", 2.50));
        drinks.add(new DrinksList(R.drawable.tonic, "Tonic Water", 2.50));
        drinks.add(new DrinksList(R.drawable.ioli, "Sparkling Water Ioli", 2.50));
        drinks.add(new DrinksList(R.drawable.perrier, "Sparkling Water Perrier", 2.50));
        drinks.add(new DrinksList(R.drawable.nero, "Still Water", 2.00));
        drinks.add(new DrinksList(R.drawable.redbull, "Red Bull", 4.00));
        drinks.add(new DrinksList(R.drawable.zelita, "Zelita", 2.50));

mAllData.addAll(drinks);
        lv = (ListView)rootView.findViewById(R.id.drinksListView);
        adapter = new MyCustomDrinksListAdapter(getActivity().getApplicationContext(),        R.layout.list_item, drinks);
        lv.setAdapter(adapter);
    }


public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        drinks .clear();
        if (charText.length() == 0) {
            drinks.addAll(mAllData);
        } else {
            for (DrinksList wp : mAllData) {
                if (wp.getName().toLowerCase(Locale.getDefault())
                        .contains(charText)) {
                    drinks .add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }

}

      

and your adapter class will remain the same (remove filter).



 public class MyCustomDrinksListAdapter extends ArrayAdapter<DrinksList> {


   // private List<DrinksList> items = null; // no use
    private ArrayList<DrinksList> arraylist;
    public MyCustomDrinksListAdapter(Context context, int layoutId, List<DrinksList> items) {
        super(context, layoutId, items);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View arrayView = convertView;
        if(arrayView == null){
            LayoutInflater vi;
            vi = LayoutInflater.from(getContext());
            arrayView = vi.inflate(R.layout.list_item, parent, false);
        }

        DrinksList currentPosition = getItem(position);
        if(currentPosition != null){
            ImageView image = (ImageView)arrayView.findViewById(R.id.product_image_coffee);
            image.setImageResource(currentPosition.getImage());

            TextView name = (TextView)arrayView.findViewById(R.id.product_name_coffee);
            name.setText(currentPosition.getName());

            TextView price = (TextView)arrayView.findViewById(R.id.product_price_coffee);
            price.setText(String.format("%.2f", currentPosition.getPrice()));
        }
        return arrayView;
    }


}

      

Thank. Hope it works ... !! 1

+7


source


The custom adapter must implement the Filterable interface, and you must override the getFilter () method.



refer to this answer: How to implement getfilter () with a custom adapter extending the base adapter .

+3


source


I figured out that the problem was with the constructor class of the MyCustomDrinksListAdapter class. Initialize an arraylist in a constructor like this:

arraylist = new ArrayList<DrinksList>();
this.arraylist.addAll(items);

      

You don't have to leave the base adapter just by changing the constructor. Another thing is that you are not familiar with the concept of ViewHolder. Find and use it in getView()

, it will improve performance. but your remaining code is correct, but the constructor. if you need any other help you can ask.

+2


source


This is the code that needs to be used to implement srach on the list:

inputSearch.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
        // When user changed the Text
        MainActivity.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                          
    }
});

      

Taken from after the tutorial. Hope this helps :)

+1


source







All Articles