Reputation: 2676
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
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
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