0

I have an edittext and a listview in my application my listview show contact list. I want listview filter with edittext. I searched a lot on google and found some examles but none worked for me here's my code my custom adapter

public class MainActivity extends AppCompatActivity {

private static final int CODE_GET_REQUEST = 1024;
private static final int CODE_POST_REQUEST = 1025;

EditText editTextHeroId, editTextName, editTextRealname, editTextComment;
Spinner spinnerTeam;
ProgressBar progressBar;
ListView listView;
Button buttonAddUpdate;
Button buttonScan;
SearchView searchView;
Adapter HeroAdapter;

private List<Hero> heroList = new ArrayList<Hero>();
boolean isUpdating = false;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editTextHeroId = (EditText) findViewById(R.id.editTextHeroId);
    editTextName = (EditText) findViewById(R.id.editTextName);
    editTextRealname = (EditText) findViewById(R.id.editTextRealname);
    editTextComment = (EditText) findViewById(R.id.editTextComment);
    spinnerTeam = (Spinner) findViewById(R.id.spinnerTeamAffiliation);

    buttonAddUpdate = (Button) findViewById(R.id.buttonAddUpdate);
    buttonScan = (Button) findViewById(R.id.buttonScan);

    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    listView = (ListView) findViewById(R.id.listViewHeroes);
    listView.setTextFilterEnabled(true);
    heroList = new ArrayList<>();

    HeroAdapter adapter = new HeroAdapter(heroList);
    final ArrayAdapter<Hero> HeroAdapter = new ArrayAdapter<Hero>(this, R.layout.layout_hero_list, heroList);
    listView.setAdapter(adapter);

    editTextName.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            HeroAdapter.getFilter().filter(cs);
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }

        @Override
        public void afterTextChanged(Editable arg0) {}

    });

Adapter

public class HeroAdapter extends ArrayAdapter<Hero> implements Filterable {

    List<Hero> heroList;

    public HeroAdapter(List<Hero> heroList) {
        super(MainActivity.this, R.layout.layout_hero_list, heroList);
        this.heroList = heroList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = getLayoutInflater();
        View listViewItem = inflater.inflate(R.layout.layout_hero_list, null, true);

        final TextView textViewName = listViewItem.findViewById(R.id.textViewName);
        TextView textViewUpdate = listViewItem.findViewById(R.id.textViewUpdate);
        TextView textViewDelete = listViewItem.findViewById(R.id.textViewDelete);

        final Hero hero = heroList.get(position);

        textViewName.setText(hero.getName());

        textViewUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isUpdating = true;
                editTextHeroId.setText(String.valueOf(hero.getId()));
                editTextName.setText(hero.getName());
                editTextRealname.setText(hero.getRealname());
                editTextComment.setText(hero.getRating());
                spinnerTeam.setSelection(((ArrayAdapter<String>) spinnerTeam.getAdapter()).getPosition(hero.getTeamaffiliation()));
                buttonAddUpdate.setText("Update");
            }
        });

        textViewDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

                builder.setTitle("Delete " + hero.getName())
                        .setMessage("Are you sure you want to delete it?")
                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                deleteHero(hero.getId());
                            }
                        })
                        .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();
            }
        });
        return listViewItem;
    }

    public Filter getFilter() {

        Filter filter = new Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                heroList = (List<Hero>) results.values;
                notifyDataSetChanged();
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                FilterResults results = new FilterResults();
                ArrayList<Hero> heroList = new ArrayList<Hero>();

                // perform your search here using the searchConstraint String.

                constraint = constraint.toString().toLowerCase();
                for (int i = 0; i < heroList.size(); i++) {
                    Hero dataNames = heroList.get(i);
                    if (dataNames.toString().toLowerCase().startsWith(constraint.toString()))  {
                        heroList.add(dataNames);
                    }
                }

                results.count = heroList.size();
                results.values = heroList;
                Log.e("VALUES", results.values.toString());

                return results;
            }
        };

        return filter;
    }
}

when i fill the keyword from edittext, the list data can't show, . any help will be appriciated. thanks in advance

Sachin Rajput
  • 4,326
  • 2
  • 18
  • 29
hawkinzieg
  • 11
  • 4

3 Answers3

0

the heroList.size() is always 0 so will not go inside the "for (int i = 0; i < heroList.size(); i++)" at all

You have to remove "ArrayList heroList = new ArrayList();" to select the GLOBAL heroList.

protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();
            **ArrayList<Hero> heroList = new ArrayList<Hero>();**

            // perform your search here using the searchConstraint String.

            constraint = constraint.toString().toLowerCase();
            for (int i = 0; i < heroList.size(); i++) {
                Hero dataNames = heroList.get(i);
                if (dataNames.toString().toLowerCase().startsWith(constraint.toString()))  {
                    heroList.add(dataNames);
                }
            }

            results.count = heroList.size();
            results.values = heroList;
            Log.e("VALUES", results.values.toString());

            return results;
        }
Hamza rasaee
  • 362
  • 4
  • 12
  • This isn't correct. The new list is to add filtered results. Removing it will delete the other data, or add duplicates – OneCricketeer Jan 12 '18 at 14:23
  • I see, but still heroList.size() is 0. The program counter will not get in to the "for". I'm not sure but maybe the local heroList is conflicting with the global one – Hamza rasaee Jan 12 '18 at 15:17
0

First, at the top of the activity

Adapter HeroAdapter;

Should be

HeroAdapter adapter;

Then you need to actually initialize that one, not a different adapter, or even two of them

this.heroList = new ArrayList<>();
this.adapter = new HeroAdapter(this, heroList);
listView.setAdapter(adapter);

After you fix the constructor for the adapter to accept a Context instead of being coupled to the MainActivity

public class HeroAdapter extends ArrayAdapter<Hero> implements Filterable {

    private List<Hero> heroList;

    public HeroAdapter(Context c, List<Hero> heroList) {
        super(c, R.layout.layout_hero_list, heroList);
        this.heroList = heroList;
    }

Then you're also "shadowing" your list with an empty one when you try to filter. Android Studio might even be pointing this out to you, if you read the warnings.

Rename it to something else

FilterResults results = new FilterResults();
List<Hero> filtered = new ArrayList<>();
constraint = constraint.toString().toLowerCase();
for (Hero h : MainActivity.this.heroList) {
     if (h.getName().toLowerCase().startsWith(constraint))  {
         filtered.add(h);
     }
 }

results.count = filtered.size();
results.values = filtered;
return results;
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
-2

You have used class name of adapter in onTextChanged() method instead of object of adapter.

Try this:

 @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
        String text = editTextName.getText().toString().toLowerCase(Locale.getDefault());
        adapter.filter(text);
    }