I'm trying to perform a search on my recycler adapter when onQueryTextChange
as shown below.
newText = newText.toLowerCase();
List<HymnDataModel> search_list = new ArrayList<>();
for(HymnDataModel hymnDataModel : hymnDataList){
String hymn_title = hymnDataModel.getHymnTitle().toLowerCase();
String hymn_subTitle = hymnDataModel.getHymnSubTitle().toLowerCase();
if (hymn_title.contains(newText) || hymn_subTitle.contains(newText)){
search_list.add(hymnDataModel);
}
}
And i filter the Adapter using the setFilter.
adapterRV.setFilter(search_list);
This is the setFilter function in my Adapter
public void setFilter(List<HymnDataModel> search_list) {
mHymnsList = new ArrayList<>();
mHymnsList.addAll(search_list);
//notify to reload
notifyDataSetChanged();
}
The search works just fine, onQueryTextChange
, but after filtering the Adapter and displaying on the RecyclerView, when i click on the filtered/searched item on my recyclerview, it doesn't open that particular item, instead, it opens another item that's not on the filtered list.
Try this instead.Assign search_list to the existing array List.
public void setFilter(List<HymnDataModel> search_list) {
mHymnsList = search_list;
//notify to reload
notifyDataSetChanged();
}
You are appending Filtered data item's in your Arraylist that's why your adapter display item that's not on the filtered list. try this clear your Arraylist before adding Filtered item in your Arraylist
Try this
public void setFilter(List<HymnDataModel> search_list) {
mHymnsList.clear();
mHymnsList.addAll(search_list);
or
mHymnsList = search_list;
//notify to reload
notifyDataSetChanged();
}
Related
I use onBindViewHolder in my CardAdapter. It includes an onClick method of checkedTextView.I am trying to get these texts and put to Arraylist(sharedP). But ArrayList only returns the last element. Where is my fault?
public void onBindViewHolder(#NonNull final CardTasarimTutucu holder, int position) {
SharedPreferences sp = mContext.getSharedPreferences("checked",Context.MODE_PRIVATE);
e=sp.edit();
sharedP= new ArrayList<>();
word = words.get(position).getMean();
Log.e("getMean",word);
id= words.get(position).getId();
str= new StringBuffer("");
holder.rowText.setText(word);
holder.rowText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (holder.rowText.isChecked()) {
sharedP.remove(sharedP.indexOf(word));
flag=false;
holder.rowText.setCheckMarkDrawable(null);
holder.rowText.setChecked(false);
} else {
sharedP.add(word);
flag=true;
Log.e("deneme",word);
holder.rowText.setCheckMarkDrawable(R.drawable.ic_check_black_24dp);
holder.rowText.setChecked(true);
}
str.delete(0,str.length());
for(int i=0;i<sharedP.size();i++){
Log.e("sharedpreference1",sharedP.get(i).toString());
str.append(sharedP.get(i));
str.append(".");
}
if(flag==false){
e.remove("str");
e.commit();
}
Log.e("size",str.toString());
e.putString("str", str.toString());
e.remove("set");
e.commit();
}
});
}
example of checkedTextView
shared preference
First of all onBindViewHolder is calling for each item in RecyclerView in order to display the data in each position in the view item. So it is like a loop. In your code you initialize the sharedP array inside onBindViewHolder sharedP= new ArrayList<>();. So for each item you pass / scroll , the array is getting initialized again and the previous item is being lost.In other words when you reach the end of your list you will have only 1 item inside your list , the last one.
I am facing a problem that when I try to dynamically add items to my spinner the app crashes. So first I add an array from Strings.xml my R.array.restrictions contains 16 items therefore I am inserting each key into 16 and then adding it onto the next position. and after that I load each item from firebase and add it to the adapter, then I set the adapter, so in my mind it should work. Any ideas why it causes a crash? Says:
UnsupportedOperationException at
java.util.AbstractList.add(AbstractList.java:148)
Thanks.
public void startSpinner(){
//built in Profiles
spinner = (Spinner) findViewById(R.id.spinnerProfiles);
adapter = ArrayAdapter.createFromResource(this, R.array.restrictions, android.R.layout.simple_spinner_item);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
map = (Map<String, Object>) dataSnapshot.child("users").child(userID).getValue();
ArrayList<String> array = new ArrayList<>();
int x = 16;
for (Map.Entry<String,Object> entry : map.entrySet()) {
// key contains Profile Name
String key = entry.getKey();
adapter.insert(key, x);
x++;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Auto Generated Method
}
});
adapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
Perhaps the problem is that you are changing an array that is coming from resources. This can happen as the list you are using is not created by you.
You can try the following:
ArrayList<CharSequence> array = new ArrayList<CharSequence>(Arrays.asList(context.getResources().getTextArray(R.array.restrictions)));
adapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, array);
I have Quote List class QuoteListFragment. where I am loading data in adapter from server like this
private ArrayList<Quote> quotes;
quotes = response.body();
NewQuoteAdapter adapter = new NewQuoteAdapter(getContext(), response.body());
mQuoteList.setAdapter(adapter);
and RecyclerView Adapter called NewQuoteAdapter
I am displaying Item in details with QuoteViewFragment. I have implemented a button called "delete" in this fragment and I want to give the user a chance to delete that quote from fragment so When the user goes back to the list, it disappears from the list.
I have no idea how to achieve this. Let me know if someone can give me a solution for this. Thanks
well you have a list, and adapter, and a recyclerview
ArrayList<String> myQuoteList = new ArrayList<String>();
MyCustomAdapter adapter = new MyCustomAdapter(myQuoteList);
rcvQuotes.setAdapter(adapter);
Then in your delete you can just do
private void deleteAtIndex(int index){
myQuoteList.remove(index);
adapter.notifyDataSetChanged();
}
//make a interface.
public interface fragmentCallback{
boolean onQuoteDeleted(Quote deleteQuote);
}
have your activity implement the interface:
myActivity implements fragmentCallback{
public boolean onQuoteDeleted(Quote deletedQuote){
if(myQuotelist.contains(deleteQuote){
myQuoteList.remove(deleteQuote);
adapter.notifyDataSetChanged();
}
}
}
then in fragment simpley
myFragment.setQuote(selectedQuote);
inside of fragment just do:
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
mFragmentCallback = (IFragmentCallback) context;
}catch (Exception ex){
A35Log.e(TAG, "Parent Context does not implement fragmentCallback");
}
}
public void setQuote(Quote showQuote){
mSelectedQuote = showQuote;
}
btnDelete_onClick(){
if(mFragmentCallback != null){
mFragmentCallback.onDeleteQuote(mSelectedQuote);
}
}
you can handle it by selected index of the row, or by last index, or first index, or you can add a long touch listener or trash can to the row item. how you get the index is up to you.
That's it, that is all there is to it.
Arraylist.remove(index)
recycleradapter.notifydatasetchanged()
Get the index of clicked item
e.g index = 4
list of quote e.g quotesList.
quotesList.remove(index);
adapter.notifyDataSetChanged();
I made a dictionary app but I search a word for example water,water does not show first line.I want to filter water or w suggestion word.Whats wrong my code?
Thnks
#Override
public boolean onQueryTextChange(String newText) {
newText = newText.toLowerCase();
final ArrayList<DictObjectModel> filteredList = new ArrayList<DictObjectModel>();
for (int i = 0; i < wordcombimelist.size(); i++) {
final String text = wordcombimelist.get(i).toLowerCase();
if (text.contains(newText) && (text.equals(newText)) ) {
filteredList.add(new DictObjectModel(wordcombimelist.get(i),meancombimelist.get(i)));
}
}
adapter = new CustomAdapter(filteredList);
recyclerView.setAdapter(adapter);
return true;
}
First of all you shouldn't be creating new Adapter each time you want to filter your list. You should implement add and remove methods in your CustomAdapter.
Here you can find instruction about filtering the RecyclerView.
I looked at the following site: ListView Example
Which describes how to implement a search function in a listview which uses the default adapter and it works fine.
How can I modify it so I can use the same for a Custom Adapter for my listview?
Partial code is:
dataList = (ListView) findViewById(R.id.lvFiles);
tvQuote = (TextView) findViewById(R.id.tvDisplay);
tvQuote.setTypeface(Typeface.createFromAsset(MainActivity.this.getAssets(), "fonts/roboto.ttf"));
for (int y=0; y<strNamesOfAllah.length;y++) {
name = strNamesOfAllah[y];
meaning = strMeaning[y];
rowsArray.add(new SetRows(R.drawable.icon, name, meaning));
}
adapter = new SetRowsCustomAdapter(MainActivity.this, R.layout.customlist, rowsArray);
dataList.setAdapter(adapter);
dataList.setClickable(true);
You need to override getFilter inside of your adapter and return a new customFilter object that you create. See this answer: No results with custom ArrayAdapter Filter
Edit:
#Override
public Filter getFilter() {
if(customFilter == null){
customFilter = new CustomFilter();
}
return customFilter;
}