0

I have a listview that has a custom adapter, and I was trying to make it searchable using an Action Item. When I click the search icon in the action bar, the edit text comes up, but when I enter text and click "done" on the keyboard, nothing happens.

Here is the main class:

public class ItemId extends SherlockListActivity {

    EditText editsearch;
    ArrayAdapter<String> adapter;

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

        Context ctx = getApplication();
        Resources res = ctx.getResources();

        String[] options = res.getStringArray(R.array.item_ids);
        String[] ids = res.getStringArray(R.array.item_names);
        TypedArray icons = res.obtainTypedArray(R.array.item_images);

        adapter = new ItemIDAdapter(ctx, R.layout.idslistitem, ids, options, icons);

        setListAdapter(adapter );
    }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Get the options menu view from menu.xml in menu folder
            getSupportMenuInflater().inflate(R.menu.items_menu, menu);

            // Locate the EditText in menu.xml
            editsearch = (EditText) menu.findItem(R.id.menu_search).getActionView();

            // Capture Text in EditText
            editsearch.addTextChangedListener(textWatcher);

            // Show the search menu item in menu.xml
            MenuItem menuSearch = menu.findItem(R.id.menu_search);

            menuSearch.setOnActionExpandListener(new OnActionExpandListener() {

                // Menu Action Collapse
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    // Empty EditText to remove text filtering
                    editsearch.setText("");
                    editsearch.clearFocus();
                    return true;
                }

                // Menu Action Expand
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    // Focus on EditText
                    editsearch.requestFocus();

                    // Force the keyboard to show on EditText focus
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                    return true;
                }
            });

            // Show the settings menu item in menu.xml
            MenuItem menuSettings = menu.findItem(R.id.home);

            // Capture menu item clicks
            menuSettings.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    Intent intent2 = new Intent(ItemId.this, Home.class);
                    startActivity(intent2);
                    return true;
                }

            });

            return true;
        }

        // EditText TextWatcher
        private TextWatcher textWatcher = new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                String text = editsearch.getText().toString()
                        .toLowerCase(Locale.getDefault());
                adapter.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

            }

        };
}

And here is the Adapter class:

public class ItemIDAdapter extends ArrayAdapter<String> implements Filterable {

    public LayoutInflater mInflater;

    public String[] mStrings;
    public String[] mIds;
    public TypedArray mIcons;   
    public int mViewResourceId;

    public ItemIDAdapter(Context ctx, int viewResourceId,
            String[] strings, String[] ids, TypedArray icons) {
        super(ctx, viewResourceId, strings);

        mInflater = (LayoutInflater)ctx.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

        mStrings = strings;
        mIds = ids;
        mIcons = icons;       
        mViewResourceId = viewResourceId;
    }

    @Override
    public int getCount() {
        return mStrings.length;
    }

    @Override
    public String getItem(int position) {
        return mStrings[position];
    }

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



    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(mViewResourceId, null);

        ImageView iv = (ImageView)convertView.findViewById(R.id.option_icon);
        iv.setImageDrawable(mIcons.getDrawable(position));

        TextView tv = (TextView)convertView.findViewById(R.id.option_text);
        tv.setText(mStrings[position]);

        TextView tv1 = (TextView)convertView.findViewById(R.id.itemids);
        tv1.setText(mIds[position]);

        return convertView;
    }


}

If anyone has any idea as to why nothing happens when I search, or knows how to fix it, it'd be greatly appreciated. Thanks!!

2

2 Answers 2

1

You need to implement a custom filter. Have a look at this post here someone else has had a similar problem which he solved: https://stackoverflow.com/a/8258457/2045570

Sign up to request clarification or add additional context in comments.

3 Comments

I'm a beginner at all this and I just do not know how to implement his custom filter, to work with my code. Do you know how I could do it?
Just follow what the person in that post has done. He has a very similar ArrayAdapter to yours. I can't give you the answer and the best way to learn is by trying it yourself.
I've been looking at the example code you provided, and I replaced it with my code to try to get something working, but it keeps telling me "FilterResults cannot be resolved to a type" and "The type LayoutInflater.Filter cannot be the superclass of CustomFilter; a superclass must be a class"
1

Below is mine code, which is working perfectly:-

public class ExpenditureAdapter extends ArrayAdapter<Expenditure> implements Filterable {
ArrayList<Expenditure> listArray;
ArrayList<Expenditure> filteredlistArray;
private Filter mFilter;
public ExpenditureAdapter(@NonNull Context context, ArrayList<Expenditure> list) {
    super(context,0, list);
    listArray=list;
    filteredlistArray=list;
}
@Override
public int getCount() {
    return filteredlistArray.size();    // total number of elements in the list
}

public void add(Expenditure object) {
    listArray.add(object);
    this.notifyDataSetChanged();
}

public Filter getFilter() {
    if (mFilter == null) {
        mFilter = new CustomFilter();
    }
    return mFilter;
}
@Override
public Expenditure getItem(int i) {
    return filteredlistArray.get(i);    // single item in the list
}
@Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}
@Override
public long getItemId(int i) {
    return i;                   // index number
}
@Override

public View getView(int position, View convertView, ViewGroup parent) {

    // Get the data item for this position

    Expenditure expenditure = getItem(position);

    // Check if an existing view is being reused, otherwise inflate the view

    if (convertView == null) {

        convertView = LayoutInflater.from(getContext()).inflate(R.layout.listexpenditure, parent, false);

    }

    // Lookup view for data population

    TextView ExpId = (TextView) convertView.findViewById(R.id.ExpId);
    TextView ExDate = (TextView) convertView.findViewById(R.id.ExDate);
    TextView ExpAmt = (TextView) convertView.findViewById(R.id.ExpAmt);
    TextView ExpDetail = (TextView) convertView.findViewById(R.id.ExpDetail);
 

    // Populate the data into the template view using the data object

    ExpId.setText(expenditure.ExpId);
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
    String dateTime = dateFormat.format(expenditure.ExpDate);
    ExDate.setText(dateTime);
    ExpAmt.setText(String.valueOf(expenditure.ExpAmt));
    ExpDetail.setText(expenditure.ExpDetail);
    return convertView;

}


private class CustomFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results = new FilterResults();

        if(constraint == null || constraint.length() == 0) {
            ArrayList<Expenditure> list = new ArrayList<Expenditure>(listArray);
            results.values = list;
            results.count = list.size();
        } else {
            ArrayList<Expenditure> newValues = new ArrayList<Expenditure>();
            for(int i = 0; i < listArray.size(); i++) {
                Expenditure e_item = listArray.get(i);
                if(e_item.ExpDetail.contains(constraint)) {
                    newValues.add(e_item);
                }
            }
            results.values = newValues;
            results.count = newValues.size();
        }
        return results;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint,
                                  FilterResults results) {
        filteredlistArray = (ArrayList<Expenditure>) results.values;
      
        notifyDataSetChanged();
    }
}

and use it in your code as below:-

private TextWatcher textWatcher = new TextWatcher() {
    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub
        String text = txtSearch.getText().toString()
                .toLowerCase(Locale.getDefault());
        adapter.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

    }

};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.