I have a RecylerView which has SearchView widget and list of items containing checkbox and player names. There is no problem when I scroll items and select items checkboxes are selected. But problem arises when ever I search items by there name and then select them, when I try to search another item the previously item gets unchecked.
When i type BAT and list of player with bat are shown then i selected 2 players
Then I remove BAT from searchview and you can see both 2 selected players get deselected
CustomAdapter.java
public class CustomAdapter extends BaseAdapter implements Filterable {
ArrayList<SomeObject> someObjects= new ArrayList<SomeObject>();
ArrayList<String> name=new ArrayList<>();
ArrayList<String> id=new ArrayList<>();
ArrayList<String> role= new ArrayList<>();
ArrayList<String> price= new ArrayList<>();
ArrayList<String> teamName= new ArrayList<>();
CheckBox chk;
int totc=0;
int batc=0;
int maxbat=3;
int bwlc=0;
int maxbal=3;
int allc=0;
int maxall=4;
ValueFilter valueFilter;
int wktc=0;
int maxwkt=1;
Context c;
ArrayList<PlayersPool> players;
ArrayList<PlayersPool> checkdata;
ArrayList<PlayersPool> searchdata;
LayoutInflater inflater;
boolean[] itemChecked;
public CustomAdapter(Context c, ArrayList<PlayersPool> players) {
this.c = c;
this.players = players;
searchdata=players;
itemChecked= new boolean[players.size()];
}
#Override
public int getCount() {
return players.size();
}
#Override
public Object getItem(int position) {
return players.get(position);
}
#Override
public long getItemId(int position)
{
return players.indexOf(getItem(position));
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (inflater==null){
inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if(convertView==null)
{
convertView=inflater.inflate(R.layout.model,null);
}
final TextView nameP= (TextView) convertView.findViewById(R.id.nameP);
TextView priceP= (TextView) convertView.findViewById(R.id.priceP);
final TextView roleP= (TextView) convertView.findViewById(R.id.roleP);
final TextView team= (TextView)convertView.findViewById(R.id.team_name);
chk= (CheckBox)convertView.findViewById(R.id.cb);
chk.setOnCheckedChangeListener(null);
chk.setFocusable(false);
nameP.setText(players.get(position).getName());
priceP.setText(players.get(position).getPrice());
roleP.setText(players.get(position).getRole());
team.setText(players.get(position).getTeamName());
if (players.get(position).isselected) {
chk.setChecked(true);
} else {
chk.setChecked(false);
}
checkdata= new ArrayList<>();
chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton cb, boolean b) {
if(b) {
players.get(position).isselected = true;
if (players.get(position).getRole().equals("BAT")) {
Toast.makeText(c,"Checked",Toast.LENGTH_SHORT).show();
batc++;
if (batc > 3) {
batc--;
totc--;
chk.setChecked(false);
players.get(position).isselected = false;
}
}
}
else {
players.get(position).isselected = false;
if(players.get(position).getRole().equals("BAT")){
batc--;
}
}
notifyDataSetChanged();
}
});
return convertView;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<PlayersPool> filterList = new ArrayList<PlayersPool>();
for (int i = 0; i < searchdata.size(); i++) {
if ((searchdata.get(i).getRole().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
final PlayersPool play = new PlayersPool();
play.setName(searchdata.get(i).getName());
play.setTeamName(searchdata.get(i).getTeamName());
play.setRole(searchdata.get(i).getRole());
play.setPrice(searchdata.get(i).getPrice());
play.setIsselected(searchdata.get(i).isselected);
filterList.add(play);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = searchdata.size();
results.values = searchdata;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
players = (ArrayList<PlayersPool>) results.values;
notifyDataSetChanged();
}
}
}
You must use loop for this.
if (players.get(position).isselected) {
chk.setChecked(true);
for(PlayersPool item: searchdata){
if(players.get(position).getName().equals(item.getName())){
item.setIsselected(true);
}
}
} else {
chk.setChecked(false);
}
Related
I am trying to implement a custom searchable spinner in my activity but something is wrong in the code and I can't find it. Look at the screenshots below to understand my problem.
snap1
Here is the original listview with three items and no search filter added yet
snap2
Here is the listview after the search filter
snap3
Here is the listview after removing the search.
So as you can see in third screenshot the listview is not showing all three items after search filter is cleared. Can you see what mistake I am making in my code?
ListAdapter.java
public class ListAdapter extends ArrayAdapter<SpinnerItem> {
private List<SpinnerItem> items;
private Context context;
private Filter filter;
public ListAdapter(#NonNull Context context, int resource, List<SpinnerItem> items) {
super(context, resource);
this.context = context;
this.items = items;
this.filter = new CustomItemsFilter();
}
#Nullable
#Override
public SpinnerItem getItem(int position) {
return items.get(position);
}
#Override
public int getCount() {
return items.size();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rootView = inflater.inflate(R.layout.list_item,parent,false);
TextView textView = rootView.findViewById(R.id.itemTitle);
TextView textView1 = rootView.findViewById(R.id.itemSubTitle);
TextView textView2 = rootView.findViewById(R.id.itemSign);
textView.setText(items.get(position).getTitle());
textView1.setText(items.get(position).getSubTitle());
textView2.setText(items.get(position).getSign());
return rootView;
}
#NonNull
#Override
public Filter getFilter() {
if(filter == null) {
filter = new CustomItemsFilter();
}
return filter;
}
private class CustomItemsFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint != null && constraint.toString().length() > 0) {
constraint = constraint.toString().toLowerCase();
List<SpinnerItem> allItems = new ArrayList<SpinnerItem>();
List<SpinnerItem> filterItems = new ArrayList<SpinnerItem>();
synchronized (this) {
allItems.addAll(items);
}
for (int i = 0; i < allItems.size(); ++i) {
SpinnerItem item = allItems.get(i);
if(item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint)) {
filterItems.add(item);
}
}
filterResults.count = filterItems.size();
filterResults.values = filterItems;
}
else {
synchronized (this) {
filterResults.values = items;
filterResults.count = items.size();
}
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.count > 0) {
items = (List<SpinnerItem>) results.values;
notifyDataSetChanged();
}
}
}
}
SpinnerDialog.java
public class SpinnerDiaglog implements SearchView.OnCloseListener, SearchView.OnQueryTextListener{
private List<SpinnerItem> items;
private OnSpinnerItemClick onSpinnerItemClick;
private Activity context;
private SearchView searchView;
private DialogInterface.OnClickListener onClickListener;
private ListAdapter adapter;
private OnSearchTextChanged onSearchTextChanged;
private ListView listView;
private AlertDialog dialog;
public SpinnerDiaglog() {
}
public SpinnerDiaglog(Activity context, List<SpinnerItem> items) {
this.context = context;
this.items = items;
}
public void onCreateDialog() {
View rootView = context.getLayoutInflater().inflate(R.layout.spinner_dialog,null);
//setData(rootView);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setView(rootView);
alertDialog.setPositiveButton("CLOSE",onClickListener);
alertDialog.setTitle("Select Item");
SearchManager searchManager = (SearchManager) context.getSystemService(Context
.SEARCH_SERVICE);
searchView = rootView.findViewById(R.id.search);
searchView.setSearchableInfo(searchManager.getSearchableInfo(context.getComponentName()));
searchView.setOnQueryTextListener(this);
searchView.setOnCloseListener(this);
searchView.setIconifiedByDefault(false);
searchView.clearFocus();
listView = rootView.findViewById(R.id.listItems);
adapter = new ListAdapter(context,R.layout.list_item,items);
listView.setAdapter(adapter);
dialog = alertDialog.create();
dialog.show();
listView.setOnItemClickListener((parent, view, position, id) -> {
onSpinnerItemClick.onClick(adapter.getItem(position),position);
dialog.dismiss();
});
}
public void setOnSpinnerItemClickListener(OnSpinnerItemClick onSpinnerItemClick) {
this.onSpinnerItemClick = onSpinnerItemClick;
}
public void setOnSearchTextChangedListener(OnSearchTextChanged onSearchTextChanged) {
this.onSearchTextChanged = onSearchTextChanged;
}
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if(TextUtils.isEmpty(newText)) {
((ListAdapter) listView.getAdapter()).getFilter().filter(null);
}
else {
((ListAdapter) listView.getAdapter()).getFilter().filter(newText);
}
if (null != onSearchTextChanged) {
onSearchTextChanged.onSearchTextChanged(newText);
}
return true;
}
public interface OnSpinnerItemClick {
void onClick(SpinnerItem item, int position);
}
public interface OnSearchTextChanged {
void onSearchTextChanged(String strText);
}
#Override
public boolean onClose() {
return false;
}
}
MainActivity.java
public class MainActivity2 extends AppCompatActivity {
private SpinnerDiaglog spinnerDiaglog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Button button = findViewById(R.id.show);
List<SpinnerItem> items = new ArrayList<>();
items.add(new SpinnerItemImp("Title","subTitle","sign"));
items.add(new SpinnerItemImp("aitle","subTitle","sign"));
items.add(new SpinnerItemImp("Tiastle","subTitle","sign"));
button.setOnClickListener(v -> {
spinnerDiaglog = new SpinnerDiaglog(MainActivity2.this,items);
spinnerDiaglog.onCreateDialog();
});
}
}
SpinnerItemImp.java
public class SpinnerItemImp implements SpinnerItem {
private String title;
private String subTitle;
private String sign;
public SpinnerItemImp(String title, String subTitle, String sign) {
this.title = title;
this.subTitle = subTitle;
this.sign = sign;
}
#Override
public String getTitle() {
return title;
}
#Override
public String getSubTitle() {
return subTitle;
}
#Override
public String getSign() {
return sign;
}
}
You are keeping a single list items which is getting modified when you apply the filter for first time . So on next filter you are actually filtering from the filtered list not the actual list .
You need to maintain a Complete list separately and apply filter on it not on the filtered List . Below is an example:
public class ListAdapter extends ArrayAdapter<SpinnerItem> {
private List<SpinnerItem> items;
private List<SpinnerItem> allItems;
private Context context;
private Filter filter;
public ListAdapter(#NonNull Context context, int resource, List<SpinnerItem> items) {
super(context, resource);
this.context = context;
this.items = items;
this.filter = new CustomItemsFilter();
allItems=new ArrayList<>(items);
}
#Override
public SpinnerItem getItem(int position) {
return items.get(position);
}
#Override
public int getCount() {
return items.size();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rootView = inflater.inflate(R.layout.list_item,parent,false);
return rootView;
}
#NonNull
#Override
public Filter getFilter() {
if(filter == null) {
filter = new CustomItemsFilter();
}
return filter;
}
private class CustomItemsFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
items.clear();
FilterResults filterResults = new FilterResults();
constraint = constraint.toString().trim().toLowerCase();
if (constraint.length() > 0) {
for (int i = 0; i < allItems.size(); ++i) {
SpinnerItem item = allItems.get(i);
if (item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint)) {
items.add(item);
}
}
} else {
items.addAll(allItems);
}
filterResults.values = items;
filterResults.count = items.size();
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
items = (List<SpinnerItem>) results.values;
notifyDataSetChanged();
}
}
}
I wrote a custom ArrayAdapter with a custom Filter for my AutoCompleteTextView. It shows everything correctly, but when I filter the suggestions and click on an item, it takes the string of the item that was at this position in the suggestion list when ALL items were shown. I made screenshot to clarify what I mean:
And this is my code:
public class AutoCompleteCountryAdapter extends ArrayAdapter<CountryItem> {
private List<CountryItem> countryList;
private List<CountryItem> filteredCountryList = new ArrayList<>();
public AutoCompleteCountryAdapter(#NonNull Context context, #NonNull List<CountryItem> countryList) {
super(context, 0, countryList);
this.countryList = countryList;
}
#Override
public int getCount() {
return filteredCountryList.size();
}
#NonNull
#Override
public Filter getFilter() {
return countryFilter;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
CountryItem countryItem = filteredCountryList.get(position);
LayoutInflater inflater = LayoutInflater.from(getContext());
if (convertView == null) {
convertView = inflater.inflate(
R.layout.country_autocomplete_row, parent, false
);
}
TextView textViewName = convertView.findViewById(R.id.text_view_name);
ImageView imageViewFlag = convertView.findViewById(R.id.image_view_flag);
textViewName.setText(countryItem.getCountryName());
imageViewFlag.setImageResource(countryItem.getFlagImage());
return convertView;
}
private Filter countryFilter = new Filter() {
private List<CountryItem> suggestions = new ArrayList<>();
#Override
protected FilterResults performFiltering(CharSequence constraint) {
suggestions.clear();
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
suggestions.addAll(countryList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (CountryItem item : countryList) {
if (item.getCountryName().toLowerCase().contains(filterPattern)) {
suggestions.add(item);
}
}
}
results.values = suggestions;
results.count = suggestions.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredCountryList.clear();
filteredCountryList.addAll((List) results.values);
notifyDataSetChanged();
}
#Override
public CharSequence convertResultToString(Object resultValue) {
return ((CountryItem) resultValue).getCountryName();
}
};
}
I solved it.
I have no idea why this did not appear in any tutorial I found (including the Materialdoc one), but you also have to override getItem in the adapter, to pick it's item from the filtered List, not the original List:
public CountryItem getItem(int position) {
return filteredCountryList.get(position);
}
i provide one adapter class that used recylerview adapter for user contact adapter that filter user contact. you can make changes your requirement according into code..
public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();
public InviteContactAdapter(Context context, List<UserContact> mContactList) {
mContext = context;
this.mContactList = mContactList;
this.mContectFilter = mContactList;
mFilter = new CustomFilter();
}
public onItemClickListener onItemClickListener;
public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
return new ItemViewHolder(view);
}
public interface onItemClickListener {
void onClick(UserContact contact);
}
#Override
public Filter getFilter() {
return mFilter;
}
#Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
final UserContact contact = mContectFilter.get(i);
itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
if (contact.isSelect())
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
else
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (contact.isSelect()) {
contact.setSelect(false);
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
} else {
contact.setSelect(true);
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
}
}
});
}
#Override
public int getItemCount() {
return mContectFilter.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView mTvUserNane, mTvUserEmail;
private ImageView mIvSelect;
public ItemViewHolder(View itemView) {
super(itemView);
mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
}
}
public List<String> getEmail() {
mEmailList.clear();
for (UserContact contact : mContectFilter) {
if (contact.isSelect()) {
mEmailList.add(contact.getUserEmail());
}
}
return mEmailList;
}
/**
* this class for filter data.
*/
class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence != null && charSequence.length() > 0) {
ArrayList<UserContact> filters = new ArrayList<>();
charSequence = charSequence.toString().toUpperCase();
for (int i = 0; i < mContactList.size(); i++) {
if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
UserContact contact = new UserContact();
contact.setUserName(mContactList.get(i).getUserName());
contact.setUserEmail(mContactList.get(i).getUserEmail());
filters.add(contact);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = mContactList.size();
results.values = mContactList;
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mContectFilter = (ArrayList<UserContact>) filterResults.values;
notifyDataSetChanged();
}
}
}
ArrayList<YourModel> arrayList = new ArrayList<>();
arrayList.addAll(yourList);
AutoCompleteAdapter autoCompleteAdapter = new AutoCompleteAdapter(context, arrayList);
autoCompleteTextView.setAdapter(brandAdapter);
autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
YourModel model = (YourModel) autoCompleteAdapter.getItem(position);
autoCompleteTextView.setText(model.getText());
autoCompleteTextView.setSelection(model.getText().length());
}
});
AutoCompleteAdapter.java
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<YourModel> originalList;
private ArrayList<YourModel> suggestions = new ArrayList<>();
private Filter filter = new CustomFilter();
public AutoCompleteAdapter(Context context, ArrayList<YourModel> originalList) {
this.context = context;
this.originalList = originalList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_filter, parent, false);
}
YourModel model = suggestions.get(position);
AppCompatTextView tvTitle = convertView.findViewById(R.id.tvTitle);
tvTitle.setText(model.getText());
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
#Override
public Object getItem(int position) {
return suggestions.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public int getCount() {
return suggestions.size();
}
#Override
public Filter getFilter() {
return filter;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
suggestions.clear();
if (originalList != null && constraint != null) {
for (int i = 0; i < originalList.size(); i++) {
if (originalList.get(i).getText().toLowerCase().contains(constraint.toString().toLowerCase().trim())) {
suggestions.add(originalList.get(i));
}
}
}
FilterResults results = new FilterResults();
results.values = suggestions;
results.count = suggestions.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
I have custom listview and I have implemented SearchView to filter data. When we type something for search listview get filter correctly, but when I clear some characters from search text listview doesn't filter data. It remain constant at last search position.
Let me explain with screenshots.
Here, List is not yet filtered. all item are present.
I am searching in two fields of each item(name and description).
In this screen I have searched from cam it shows me correct result.
I have clear text till c and I am expecting resut should be two item i.e. camera and LED TV.
Here is my code.
RateListAdapter.java
public class RateListAdapter extends BaseAdapter implements Filterable {
Context context;
private SparseBooleanArray mSelectedItemsIds;
public ArrayList<RateList> itemRateList;
public LayoutInflater inflater = null;
public ArrayList<RateList> tempList;
CustomFilter filter;
public RateListAdapter(Context context, ArrayList<RateList> itemRateList) {
this.context = context;
this.itemRateList = itemRateList;
mSelectedItemsIds = new SparseBooleanArray();
this.tempList = itemRateList;
}
#Override
public int getCount() {
return itemRateList.size();
}
#Override
public RateList getItem(int i) {
return itemRateList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
class Holder {
TextView tv_name, tv_description, tv_amount;
ImageView iv_itemImage;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
Holder h = new Holder();
RateList rateList = itemRateList.get(i);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.rate_list_item, viewGroup, false);
}
h.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
h.tv_description = (TextView) convertView.findViewById(R.id.tv_description);
h.tv_amount = (TextView) convertView.findViewById(R.id.tv_amount);
h.iv_itemImage = (ImageView) convertView.findViewById(R.id.iv_itemImage);
h.tv_name.setText(rateList.Name);
h.tv_description.setText(rateList.description);
h.tv_amount.setText("₹ "+rateList.amount);
Picasso.with(context).load(rateList.image).resize(92,92).into(h.iv_itemImage);
return convertView;
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
#Override
public Filter getFilter() {
if(filter == null)
{
filter=new CustomFilter();
}
return filter;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint != null && constraint.length()>0) {
constraint=constraint.toString().toLowerCase();
ArrayList<RateList> filters=new ArrayList<RateList>();
for(int i=0;i<itemRateList.size();i++) {
if (itemRateList.get(i).Name.toLowerCase().contains(constraint) ||
itemRateList.get(i).description.toLowerCase().contains(constraint)) {
RateList r = new RateList();
r.Name = itemRateList.get(i).Name;
r.description= itemRateList.get(i).description;
r.id = itemRateList.get(i).id;
r.image = itemRateList.get(i).image;
r.amount = itemRateList.get(i).amount;
filters.add(r);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count=itemRateList.size();
results.values=itemRateList;
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
itemRateList=(ArrayList<RateList>) results.values;
notifyDataSetChanged();
}
}
}
searchview code of
BookingFrament.java
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String searchQuery) {
rateListAdapter.getFilter().filter(searchQuery);
return false;
}
});
Please help.
This is because you are modifying the itemRateList
Check this method:
#Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
itemRateList=(ArrayList<RateList>) results.values;
notifyDataSetChanged();
}
I will suggest to store the result in a separate arrayList and use it in for you adapter class.
Due to the above result being updated in the original itemRateList, so next time when the performFiltering method is invoked. You are iterating just the previous result and NOT the original list.
Hope this helps.
I am new to Android. I called lv.setOnItemClickListener to pick a selected item from ListView and show the data in a new activity through a new intent. But I don't know the could to do this works. I need some help.
MainActivity
public class MainActivity extends Activity implements
SearchView.OnQueryTextListener {
ListView lv;
SearchView search_view;
String[] country_names, iso_codes;
TypedArray country_flags;
ArrayList<Country> countrylist;
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.list_view);
search_view = (SearchView) findViewById(R.id.search_view);
country_names = getResources().getStringArray(R.array.country_names);
iso_codes = getResources().getStringArray(R.array.iso_Code);
country_flags = getResources().obtainTypedArray(R.array.country_flags);
countrylist = new ArrayList<Country>();
for (int i = 0; i < country_names.length; i++) {
Country country = new Country(country_names[i], iso_codes[i],
country_flags.getResourceId(i, -1));
countrylist.add(country);
}
adapter = new CustomAdapter(getApplicationContext(), countrylist);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
**// I DON'T KNOW WHAT PUT HERE**
}
});
search_view.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
}
Country
public class Country {
String name;
int flag;
String iso_code;
Country(String name, String iso_code, int flag) {
this.name = name;
this.iso_code = iso_code;
this.flag = flag;
}
public String getIso_code() {
return iso_code;
}
public void setIso_code(String iso_code) {
this.iso_code = iso_code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFlag() {
return flag;
}
public void setFlag(int flag) {
this.flag = flag;
}
}
Custom Adapter
public class CustomAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Country> countrylist;
ArrayList<Country> mStringFilterList;
ValueFilter valueFilter;
CustomAdapter(Context context, ArrayList<Country> countrylist) {
this.context = context;
this.countrylist = countrylist;
mStringFilterList = countrylist;
}
#Override
public int getCount() {
return countrylist.size();
}
#Override
public Object getItem(int position) {
return countrylist.get(position);
}
#Override
public long getItemId(int position) {
return countrylist.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
TextView name_tv = (TextView) convertView.findViewById(R.id.name);
TextView iso_tv = (TextView) convertView.findViewById(R.id.code);
ImageView iv = (ImageView) convertView.findViewById(R.id.flag);
Country country = countrylist.get(position);
name_tv.setText(country.getName());
iso_tv.setText(country.getIso_code());
iv.setImageResource(country.getFlag());
}
return convertView;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Country> filterList = new ArrayList<Country>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).getName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
Country country = new Country(mStringFilterList.get(i)
.getName(), mStringFilterList.get(i)
.getIso_code(), mStringFilterList.get(i)
.getFlag());
filterList.add(country);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
countrylist = (ArrayList<Country>) results.values;
notifyDataSetChanged();
}
}
}
Intent intent=new Intent(getActivity(),StartAnotherActitivity.class);
intent.putExtra(key,value);
startActivity(intent);
http://developer.android.com/reference/android/content/Intent.html
Here are the steps.
Get the position of the item clicked: This value will be passed to the method onItemClick
Now put this value as an Intent extra when you try to start the next activity
Read the index of the clicked item from your next Activity
Fetch the contents of the detail activity
Intent intent = new Intent(MainActivity.this,NewActivity.class);
intent.putExtra("Counttry",countrylist.get(arg2));
startActivity(intent);
I am extending the Array Adapter as it follows but I get still the old results can you please tell me what is the problem ?
public class Adaptor extends ArrayAdapter<String> implements Filterable{
private ArrayList<String> items;
public Adaptor(Context context, int textViewResourceId, String[] objects) {
super(context, textViewResourceId, objects);
items = new ArrayList<String>();
for (int i = 0; i < objects.length ; i++)
items.add(objects[i]);
}
#Override
public int getCount() {
return items.size();
}
#Override
public String getItem(int position) {
return items.get(position);
}
#Override
public Filter getFilter() {
Filter myFilter = new Filter(){
#Override
protected FilterResults performFiltering(CharSequence arg0) {
FilterResults rezultate = new FilterResults();
ArrayList<String> chestii = new ArrayList<String>();
for (int i = 0; i < items.size() ; i++)
{
String tmp = items.get(i).toUpperCase();
if (tmp.startsWith(arg0.toString().toUpperCase()))
chestii.add(items.get(i));
}
rezultate.count = chestii.size();
rezultate.values = chestii;
return rezultate;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results != null && results.count > 0)
{
notifyDataSetChanged();
}
else notifyDataSetInvalidated();
}
};
return myFilter;
}
}
Your list contains items from "items" and you don't modify items in it, you have to remove positions from "items" and then call notifyDataSetChange, to restore lately all items you have to save previous items
this is works fine:
/**
* Adapter wrapper to represent list of dialogs
* #author Ryazantsev Dmitry
* #email dilix90#gmail.com 2012
*/
public class FriendsAdapter extends ArrayAdapter<User>
{
private final LayoutInflater inflater;
private final ImageLoader il;
private Context parentContext;
private List<User> mData;
private List<User> mOriginalData;
public SimpleImageLoader sil;
#Override
public void add(User object)
{
if (mOriginalData != null)
mOriginalData.add(object);
else
mData.add(object);
}
#Override
public void remove(User object)
{
if (mOriginalData != null)
mOriginalData.remove(object);
else
mData.remove(object);
}
#Override
public int getCount()
{
return mData.size();
}
#Override
public User getItem(int position)
{
return mData.get(position);
}
#Override
public int getPosition(User item)
{
return mData.indexOf(item);
}
public FriendsAdapter(Context context, int textViewResourceId, List<User> objects)
{
super(context, textViewResourceId, objects);
Log.v("refresh", context + " " + textViewResourceId + " " + objects);
parentContext = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
il = new ImageLoader(context);
mData = objects;
sil = new SimpleImageLoader(context, true, 64);
sil.setOnUiThread(false);
}
/**
* We have a custom view and need to organize it
*/
#Override
public View getView(final int position, View convertView, final ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.friends_list_row, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.friendName);
holder.root = convertView.findViewById(R.id.root);
holder.photo = (ImageView) convertView.findViewById(R.id.friendPhoto);
holder.online = (ImageView) convertView.findViewById(R.id.online);
convertView.setTag(holder);
}
else
holder = (ViewHolder) convertView.getTag();
User user = getItem(position);
holder.online.setVisibility(user.isOnline() > 0 ? View.VISIBLE : View.GONE);
if (user != null)
{
holder.name.setText(user.getFIO());
holder.photo.setTag(user.getPhotoUrl());
if (user.getPhotoBitmap() != null)
holder.photo.setImageBitmap(user.getPhotoBitmap());
else
{
holder.photo.setImageResource(R.drawable.contact_nophoto);
sil.displayImageUserAttach(holder.photo, user.getPhotoUrl(), user, null, false, null);
}
}
// parent.setVisibility(position % 2 == 0?View.GONE:View.VISIBLE);
return convertView;
}
private static class ViewHolder
{
public TextView name;
public ImageView photo;
public View root;
public View online;
}
#Override
public Filter getFilter()
{
return new Filter()
{
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
Log.v("filter", "filter finished");
mData = (List<User>) results.values;
if (results.count > 0)
{
notifyDataSetChanged();
}
else
{
notifyDataSetInvalidated();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint)
{
Log.v("filter", "filter perform");
if (mOriginalData == null)
mOriginalData = new ArrayList<User>(mData);
List<User> result;
FilterResults r = new FilterResults();
if (constraint == null || constraint.length() <= 0)
result = new ArrayList<User>(mOriginalData);
else
{
result = new ArrayList<User>();
for (int i = 0; i < mOriginalData.size(); i++)
if (constraint.length() > 0
&& mOriginalData.get(i).getFIO().toLowerCase()
.contains(constraint.toString().toLowerCase()))
result.add(mOriginalData.get(i));
}
r.values = result;
r.count = result.size();
return r;
}
};
}
}