Stillie
Stillie

Reputation: 2676

Filtering on a list

I have a list of Countries and I am using it as a search, so if I am searching for a specific country, once its found the country I want, I selected it from the filtered list. The problem is, when I select the 112th item on the filtered list, if it is at the top of the filtered list, the result is actually the 1st item on the unfiltered list.

This will be an easier way of explaining it, I've uploaded a video to it which can be found here Search Example

my Adapter for the Search is here:

    public Context mContext;
public ArrayList<Countries> countryArrayList;
public ArrayList<Countries> original;

public CountryAdapter(Context context, ArrayList<Countries> countryArrayList) {
    mContext = context;
    this.countryArrayList = countryArrayList;
}

@Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}

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

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

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    CountryHolder holder;

    if (convertView == null) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.search_results_row_list, parent, false);
        holder = new CountryHolder();
        holder.countryName = (TextView) convertView.findViewById(R.id.country_text);
        holder.countryFlag = (ImageView) convertView.findViewById(R.id.country_flag);
        convertView.setTag(holder);
    } else {
        holder = (CountryHolder) convertView.getTag();
    }
    holder.countryName.setText(countryArrayList.get(position).getCountryName());
//        holder.countryFlag.setImageResource(countryArrayList.get(position).getImgId());
    return convertView;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults oReturn = new FilterResults();
            final ArrayList<Countries> results = new ArrayList<>();
            if (original == null)
                original = countryArrayList;
            if (constraint != null) {
                if (original != null && original.size() > 0) {
                    for (final Countries g : original) {
                        if (g.getCountryName()
                                .contains(constraint.toString()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

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

public class CountryHolder {
    TextView countryName;
    ImageView countryFlag;
}

Sorry I forgot where I am actually selecting the country

private void setSearchResultsList() {
    final CountryAdapter countryAdapter = new CountryAdapter(getActivity(), controller.getCountriesArrayList());
    countryAdapter.getFilter().filter(searchPhrase);
    countryAdapter.notifyDataSetChanged();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


            String selectedCountry = controller.getCountriesArrayList().get(+position).getCountryName();
            mISearch.searchResult(selectedCountry);

        }
    });

    listView.setAdapter(countryAdapter);
}

Thanks

Upvotes: 0

Views: 128

Answers (2)

Selvin
Selvin

Reputation: 6797

Once for all the time: If you are using AdapterView.setOnItemClickListener, the right way to get clicked item is such implementation:

adapterView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Object item = parent.getItemAtPosition(position);
    }
});

parent.getItemAtPosition(position) returns Adapter.getItem(position) from your adapter used in AdapterView (with setAdapter)

so for example:

  • if you are using ArrayAdapter<T> you should cast parent.getItemAtPosition(position) to T and use it ...

  • for ArrayAdapter<POJO> use:

    POJO item = (POJO)parent.getItemAtPosition(position);

  • if you are using CursorAdapter

    • Cursor c = (Cursor)parent.getItemAtPosition(position);
  • if you are using SimpleAdapter

    • Map<String, ?> item = ( Map<String, ?>)parent.getItemAtPosition(position);

of course it depends on your Adapter implementation ... so you should remeber that Adapter should return the right object with getItem(position)

As it is stated in the documentation it apply to: ListView, GridView, Spinner, Gallery and other subclasses of AdapterView

So in your case the right way is obviously:

Countries country = (Countries)parent.getItemAtPosition(position);

Upvotes: 2

Dhaval Parmar
Dhaval Parmar

Reputation: 18978

do this way


add one method in adapter class to get current list

public ArrayList<Countries> GetCurrentListData() {
        return countryArrayList;
    }

CountryAdapter dcAdapter = new CountryAdapter("whatever your perameter");
    listview.setAdapter(dcAdapter);
    lstDoctorsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view,
                                                int position, long id) {
                            try {
                                Countries countries = dcAdapter
                                     .GetCurrentListData().get(position);
                                // get data from countries model class

                            } catch (Exception e) {

                            }
                        }
                    });

Upvotes: 0

Related Questions