Loading the filtered items to search output
Asked Answered
S

1

1

I have implement search for my application. For that I have used an adapter as well. I have loaded 30 items to the search screen. When I pressed letter z to search, then letter z belongs to 4 items out of 30 items in the list.

According to the below shown code it identifies the number 4 and shows the first 4 items out of the 30 items. When I debug inside getFilter(), it shows the filtered items correctly(I have provided a screen shot).

My problem is how can I load the filtered items. Bit confused here.

search.java

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

    new SearchMenuAsyncTask(getApplicationContext(), this).execute();
    listtv = (LinearLayout) findViewById(R.id.product_lv);

    lv = (ListView) findViewById(R.id.list_view);
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    lv.setTextFilterEnabled(true);
    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            System.out.println("Text ["+s+"]");

            adapter.getFilter().filter(s.toString());

            TextView headerTV = (TextView) findViewById(R.id.search_header);
            headerTV.setText("SEARCH RESULTS");
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}

@Override
public void onTaskCompleted(JSONArray responseJson) {

    try {

        final List<String> menudescriptions = new ArrayList<String>();

        for (int i = 0; i < responseJson.length(); ++i) {
            final JSONObject object = responseJson.getJSONObject(i);

            if ((object.getString("MainCategoryID")).equals("1")
                    && (object.getString("SubCategoryID")).equals("1")
                    && (object.getString("Visible")).equals("true")) {

                Log.i("descriptionsTop ", object.getString("Description"));
                descriptions.add(object.getString("Description"));
                Log.i("MenuDescription ",
                        object.getString("MenuDescription"));
                menudescriptions
                        .add(object.getString("MenuDescription"));
            }

            adapter = new CustomListSearch(
                    getApplicationContext(), descriptions,
                    menudescriptions);
            lv.setAdapter(adapter);

        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

CustomListSearch.java

public class CustomListSearch extends BaseAdapter implements Filterable {

    private Context context;
    List<String> descriptions;
    private List<String>filteredDescriptions;
    private final List<String> menudescriptions;
    private ItemFilter mFilter = new ItemFilter();
    private LayoutInflater mInflater;
    ArrayAdapter<String> adapter;

    public CustomListSearch(Context c, List<String> data,
            List<String> menudescriptions) {
        this.context = c;
        this.filteredDescriptions = data ;
        this.descriptions = data;
        this.menudescriptions = menudescriptions;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return filteredDescriptions.size();
    }

    @Override
    public Object getItem(int position) {
        return filteredDescriptions.get(position);
    }

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

    private class ViewHolder {
        private TextView tvMenudescriptions;
        private TextView tvDescriptions;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();

            convertView = LayoutInflater.from(context).inflate(
                    R.layout.search_list_item, parent, false);

            holder.tvDescriptions = (TextView) convertView
                    .findViewById(R.id.product_name);
            holder.tvMenudescriptions = (TextView) convertView
                    .findViewById(R.id.product_description);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvDescriptions.setText(descriptions.get(position));
        holder.tvMenudescriptions.setText(menudescriptions.get(position));

        LinearLayout itemlist = (LinearLayout) convertView
                .findViewById(R.id.product_lv);
        itemlist.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Still under constructions...",
                        Toast.LENGTH_LONG).show();
            }
        });

        return convertView;
    }

    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        return mFilter;
    }

    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filterString = constraint.toString().toLowerCase();

            FilterResults results = new FilterResults();

            final List<String> list = descriptions;

            int count = list.size();
            final ArrayList<String> nlist = new ArrayList<String>(count);

            String filterableString ;

            for (int i = 0; i < count; i++) {
                filterableString = list.get(i);
                if (filterableString.toLowerCase().contains(filterString)) {
                    nlist.add(filterableString);
                }
            }

            results.values = nlist;
            results.count = nlist.size();

            return results;
        }

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

    }

}

Screen shot

enter image description here

Submarginal answered 30/3, 2015 at 7:19 Comment(0)
E
1

To filter adapter that contains list of custom object

Create a Object:

public class TvObject {

    String name;
    String description;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

After:

public class CustomListSearch extends BaseAdapter implements Filterable {

    private Context context;

    private ItemFilter mFilter = new ItemFilter();
    private LayoutInflater mInflater;

    private List<TvObject> mListTvObject = new ArrayList<>();
    private List<TvObject> mListTvObjectFiltered = new ArrayList<>();

    public CustomListSearch(Context c, List<TvObject> mListTvObject) {
        this.context = c;
        mInflater = LayoutInflater.from(context);
        this.mListTvObject = mListTvObject;
        this.mListTvObjectFiltered = mListTvObject;
    }

    @Override
    public int getCount() {
        return mListTvObjectFiltered.size();
    }

    @Override
    public Object getItem(int position) {
        return mListTvObjectFiltered.get(position);
    }

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

    private class ViewHolder {
        private TextView tvMenudescriptions;
        private TextView tvDescriptions;
    }

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

        ViewHolder holder;

        if (convertView == null) {

            holder = new ViewHolder();

            convertView = mInflater.inflate(R.layout.search_list_item, parent, false);

            holder.tvDescriptions = (TextView) convertView.findViewById(R.id.product_name);
            holder.tvMenudescriptions = (TextView) convertView.findViewById(R.id.product_description);
            convertView.setTag(holder);

        } else {

            holder = (ViewHolder) convertView.getTag();
        }

        holder.tvDescriptions.setText(mListTvObjectFiltered.get(position).getName());
        holder.tvMenudescriptions.setText(mListTvObjectFiltered.get(position).getDescription());

        LinearLayout itemlist = (LinearLayout) convertView.findViewById(R.id.product_lv);

        itemlist.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Still under constructions...",Toast.LENGTH_LONG).show();
            }
        });

        return convertView;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filterString = constraint.toString().toLowerCase();

            FilterResults results = new FilterResults();

            int count = mListTvObject.size();
            final ArrayList<TvObject> mListResult = new ArrayList<>();

            String name;

            for (int i = 0; i < count; i++) {

                TvObject mTvObject = mListTvObject.get(i);
                name = mTvObject.getName();

                if (name.toLowerCase().contains(filterString)) {
                    mListResult.add(mTvObject);
                }
            }

            results.values = mListResult;
            results.count = mListResult.size();

            return results;
        }

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

Edited:

In your Activity do something like this!

try {

    final List<TvObject > mListObjects = new ArrayList<>();

    for (int i = 0; i < responseJson.length(); ++i) {

        final JSONObject object = responseJson.getJSONObject(i);

        if ((object.getString("MainCategoryID")).equals("1")
                && (object.getString("SubCategoryID")).equals("1")
                && (object.getString("Visible")).equals("true")) {


             Log.i("descriptionsTop ", object.getString("Description"));
             Log.i("MenuDescription ", object.getString("MenuDescription"));

            TvObject mTvObject = new TvObject();
            mTvObject.setName(object.getString("Description"));    
            mTvObject.setDescription(object.getString("MenuDescription"));

            mListObjects.add(mTvObject);

        }

        adapter = new CustomListSearch( getApplicationContext(), mListObjects);
        lv.setAdapter(adapter);

    }

} catch (JSONException e) {
    e.printStackTrace();
}
Egestion answered 31/3, 2015 at 12:49 Comment(3)
adapter = new CustomListSearch( getApplicationContext(), descriptions, menudescriptions); what are the changes should be done to this in activity classSubmarginal
awsome post bro.. was looking for this for a long time.Submarginal
I have another issue, do you mind taking a look at it.. #29231626Submarginal

© 2022 - 2024 — McMap. All rights reserved.