Implementing Automatic Filter on SearchView android - java

I am working on a note application whereby the added notes are displayed in alistView.
I included a search bar as one of the menu items so as to filter individual notes when the user tries to search.
For now, I have implemented the filterable feature for my listView but it's not working as expected. It's not filtering automatically when the user starts typing a letter.
The user has to do it manually by clicking on the enter button on his device for the search function to be performed and even when the searchView is empty, the listViewitems don't reappear.
How do I make sure that the search function is done automatically when the user starts typing a letter just like the way most search functionalities are?
// menumain.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/search"
android:orderInCategory="100"
app:actionViewClass= "android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"
android:icon="#drawable/ic_search"
android:title="#string/search" />
</menu>
//Main Activity
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
na.getFilter().filter(query);
if (!query.equals("")) {
na.getFilter().filter(query);
nb.getFilter().filter(query);
} else {
mListNotes.setAdapter(na);
mGridNotes.setAdapter(nb);
}
return false;
}
}
// Note.java
public class Note implements Serializable {
private long mDateTime; //creation time of the note
private String mTitle; //title of the note
private String mContent; //content of the note
public Note(long dateInMillis, String title, String content) {
mDateTime = dateInMillis;
mTitle = title;
mContent = content;
}
public void setDateTime(long dateTime) {
mDateTime = dateTime;
}
public void setTitle(String title) {
mTitle = title;
}
public void setContent(String content) {
mContent = content;
}
public long getDateTime() {
return mDateTime;
}
public String getTitle() {
return mTitle;
}
public String getContent() {
return mContent;
}
}
// Note List Adapter
class NoteListAdapter extends ArrayAdapter<Note> implements Filterable{
List<Note> objects;
private List<Note> mStringFilterList;
Filter filter;
private static final int WRAP_CONTENT_LENGTH = 5;
public NoteListAdapter(Context context, int resource, List<Note> objects) {
super(context, resource, objects);
this.objects = objects;
this.mStringFilterList = objects;
}
#Override
public int getCount() {
return objects.size();
}
#Nullable
#Override
public Note getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public Filter getFilter() {
filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Note> tempList= new ArrayList<>();
FilterResults results = new FilterResults();
if (constraint != null && objects != null) {
for(Note singleNote : objects) {
if( singleNote.getTitle().contains(constraint))
tempList.add(singleNote);
}
results.values = tempList;
results.count = tempList.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
objects = (ArrayList<Note>) results.values;
notifyDataSetChanged();
}
};
return filter;
}
}
return convertView;
}
}

You need to add filtering code in onQueryTextChange method also. This method is called each time a keystroke is fired from keyboard.
Do like this in your main activity on :
//Main Activity
#Override
public boolean onQueryTextSubmit(String query) {
na.getFilter().filter(query);
nb.getFilter().filter(query);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
na.getFilter().filter(newText);
nb.getFilter().filter(newText);
return true;
}

Related

Search Filter in RecyclerView not showing anything

My app consists in letting you add lists in which you can keep your notes. Therefore, I have this
NotesListActivity where I can add and keep my Lists. I wanted to filter this lists following the https://www.youtube.com/watch?v=CTvzoVtKoJ8 tutorial and then I tried to adapt it to my code like below. Could you please tell me what is the problem here, cause I don't even get an error, I just not get any title of list as result.
So, this is what I have in my RecyclerAdapter:
public class NotesRecyclerAdapter extends RecyclerView.Adapter<NotesRecyclerAdapter.ViewHolder> implements Filterable {
private static final String TAG = "NotesRecyclerAdapter";
ArrayList<Note> notesListAll;
private ArrayList<Note> mNotes;
private OnNoteListener mOnNoteListener;
public NotesRecyclerAdapter(ArrayList<Note> mNotes, OnNoteListener onNoteListener) {
this.mNotes = mNotes;
this.mOnNoteListener = onNoteListener;
this.notesListAll = new ArrayList<>();
notesListAll.addAll(mNotes);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
...
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
...
}
#Override
public int getItemCount() {
return mNotes.size();
}
#Override
public Filter getFilter() { return myFilter; }
Filter myFilter = new Filter() {
//runs on background thread
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
List<Note> filteredList = new ArrayList<>();
if (charSequence == null || charSequence.length() == 0) {
filteredList.addAll(notesListAll);
} else {
for (Note note : notesListAll) {
if (note.getTitle().toLowerCase().contains(charSequence.toString().toLowerCase())) {
filteredList.add(note);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
//runs on a ui thread
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mNotes.clear();
mNotes.addAll((Collection <? extends Note>) filterResults.values );
notifyDataSetChanged();
}
};
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
...
}
#Override
public void onClick(View view) {
...
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
And this in my Activity:
public class NotesListActivity extends AppCompatActivity implements
NotesRecyclerAdapter.OnNoteListener,
FloatingActionButton.OnClickListener
{
private static final String TAG = "NotesListActivity";
private RecyclerView mRecyclerView;
private ArrayList<Note> mNotes = new ArrayList<>();
private NotesRecyclerAdapter mNoteRecyclerAdapter;
private NoteRepository mNoteRepository;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
initRecyclerView();
mNoteRepository = new NoteRepository(this);
retrieveNotes();
setSupportActionBar((Toolbar)findViewById(R.id.notes_toolbar));
setTitle("Notes");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search,menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// NotesRecyclerAdapter.getFilter().filter(newText);
mNoteRecyclerAdapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
private void retrieveNotes() {
mNoteRepository.retrieveNotesTask().observe(this, new Observer<List<Note>>() {
#Override
public void onChanged(#Nullable List<Note> notes) {
...
}
});
}
private void initRecyclerView(){
...
}
#Override
public void onNoteClick(int position) {
...
}
#Override
public void onClick(View view) {
...
}
private void deleteNote(Note note) {
...
}
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
deleteNote(mNotes.get(viewHolder.getAdapterPosition()));
}
};
}
You need to check if it's the first intance or not.
if (firstInstance) {notesList.clear();}
notesList.addAll(notesListAll);
The problem is that you are using an empty notesListAll list for filtering results; you need to populate it with the list of notes in the constructor
public NotesRecyclerAdapter(ArrayList<Note> mNotes, OnNoteListener onNoteListener) {
this.mNotes = mNotes;
this.mOnNoteListener = onNoteListener;
this.notesListAll = new ArrayList<>(); // <---- Empty list
notesListAll.addAll(mNotes); // <--- Fix is here
}
Also, you're filtering based on getContent(), probably the searched text is not a part of that content, so you need to filter out some other results within the Note data class.
if (note.getContent().toLowerCase().contains(charSequence.toString().toLowerCase())) {
I just solved it out this way
notesListAll.addAll(mNotes);
to
notesListAll = mNotes;

Unable to implement Filterable to Object type ArrayList

Am trying to implement Filterable in my recyclerview which contains <Object> here is the code
private Filter exampleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Object> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(mRecyclerViewItemsAll);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Object item : mRecyclerViewItemsAll) {
if (item.getVideo_name().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mRecyclerViewItems.clear();
mRecyclerViewItems.addAll((List) results.values);
notifyDataSetChanged();
}
};
When i try above code i get cannot resolve method getVideo_name() in Object
So how do i implement Filterable. I have used same code with <String> and it worked.
Recycler view adapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
private static final int MENU_ITEM_VIEW_TYPE = 0;
private static final int UNIFIED_NATIVE_AD_VIEW_TYPE = 1;
private final Context mContext;
private final ArrayList<Object> mRecyclerViewItems;
ArrayList<Object> mRecyclerViewItemsAll;
public RecyclerViewAdapter(Context context, ArrayList<Object> recyclerViewItems) {
this.mContext = context;
this.mRecyclerViewItems = recyclerViewItems;
this.mRecyclerViewItemsAll = new ArrayList<>(recyclerViewItems);
}
#Override
public Filter getFilter() {
return exampleFilter;
}
private Filter exampleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Object> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(mRecyclerViewItemsAll);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Object item : mRecyclerViewItemsAll) {
if (item.getVideo_name().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mRecyclerViewItems.clear();
mRecyclerViewItems.addAll((List) results.values);
notifyDataSetChanged();
}
};
public class VideoAdapterViewHolder extends RecyclerView.ViewHolder{
}
#Override
public int getItemCount() {
return mRecyclerViewItems.size();
}
#Override
public int getItemViewType(int position) {
Object recyclerViewItem = mRecyclerViewItems.get(position);
if (recyclerViewItem instanceof UnifiedNativeAd) {
return UNIFIED_NATIVE_AD_VIEW_TYPE;
}
return MENU_ITEM_VIEW_TYPE;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
}
private void populateNativeAdView(UnifiedNativeAd nativeAd, UnifiedNativeAdView adView) {
}
And here is MainActivity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actionbar_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
recyclerViewAdapter.getFilter().filter(newText);
return false;
}
});
return true;
}
Can someone help me what wrong am doing and how to correct it.
cannot resolve method getVideo_name() in Object
Your list is type of Object which is super class in Java and does not contain method called getVideo_name()
Object class has predefined method namely:
toString()
hashCode()
clone()
equals(Object obj)
getClass()
finalize()
wait()
notify()
notifyAll()
What you can do is to create your class that is by default subtype of Object class and define class behavious(methods)
For example:
class MyData {
private String name;
public String getVideoName() {
return this.name;
}
public void setVideoName(String name) {
this.name = name;
}
}
And then use it like :
private final ArrayList<MyData> mRecyclerViewItems;

Implementing Filterable on Array Adapter

I need help in implementing filterable interface for my list view items in a note app am currently working on. I have tried several ways but am not getting the expected result. For now it just does nothing after tying a search item.
I have implemented all the necessary methods in my adapter class and main activity.
I really need some help as i am quite new to this.Thanks in anticipation for positive replies.
// Note.java
public class Note implements Serializable {
private long mDateTime; //creation time of the note
private String mTitle; //title of the note
private String mContent; //content of the note
public Note(long dateInMillis, String title, String content) {
mDateTime = dateInMillis;
mTitle = title;
mContent = content;
}
public void setDateTime(long dateTime) {
mDateTime = dateTime;
}
public void setTitle(String title) {
mTitle = title;
}
public void setContent(String content) {
mContent = content;
}
public long getDateTime() {
return mDateTime;
}
}
public String getTitle() {
return mTitle;
}
public String getContent() {
return mContent;
}
}
// ArrayAdapter which implements Filterable
class NoteListAdapter extends ArrayAdapter<Note> implements Filterable{
List<Note> objects;
private List<Note> mStringFilterList;
Filter filter;
private static final int WRAP_CONTENT_LENGTH = 5;
public NoteListAdapter(Context context, int resource, List<Note> objects) {
super(context, resource, objects);
this.objects = objects;
this.mStringFilterList = objects;
}
#Override
public int getCount() {
return objects.size();
}
#Nullable
#Override
public Note getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public Filter getFilter() {
filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Note> tempList=new ArrayList<Note>();
FilterResults results = new FilterResults();
if (constraint != null && objects != null) {
for(Note singleNote : objects) {
if( singleNote.getTitle().contains(constraint))
tempList.add(singleNote);
}
results.values = tempList;
results.count = tempList.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
objects = (ArrayList<Note>) results.values;
notifyDataSetChanged();
}
};
return filter;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.list_component, parent, false);
}
return convertView;
}
}
// Main Activity
#Override
public boolean onQueryTextSubmit(String query) {
ArrayList<Note> notes = Utilities.getAllSavedNotes(getApplicationContext());
final NoteListAdapter na = new NoteListAdapter(this, R.layout.list_component, notes);
na.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
}
You're returning super.getFilter() instead of your filter you just created. And also, you're not filtering anything in the Filter performFiltering() method as you're adding every item to the results if the CharSequence has something and the adapter has items.
I would suggest something like that:
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Note> tempList=new ArrayList<Note>();
FilterResults results = new FilterResults();
if (constraint != null && objects != null) {
for(Note singleNote : objects) {
if( singleNote.getTitle().contains(constraint)
tempList.add(singleNote);
}
results.values = tempList;
results.count = tempList.size();
}
return results;
}
EDITS:
Also, in the activity, inside the
#Override
public boolean onQueryTextSubmit(String query) {
ArrayList<Note> notes = Utilities.getAllSavedNotes(getApplicationContext());
final NoteListAdapter na = new NoteListAdapter(this, R.layout.list_component, notes);
na.getFilter().filter(query);
return false;
}
You're using a new adapter without setting it to the recyclerView/listView.
Try using the adapter you create inside the onCreate() of the activity or try using recyclerView/listView.setAdapter(na) after you change the adapter using the na.getFilter().filter(query);
EDITS2:
So, if you want your filter to be performed whenever the user input something move the code from the onQueryTextSubmit() to the onQueryTextChanged().
For the improvement you asked for (when the string is empty reload the full list) you have 2 ways:
First way:
#Override
public boolean onQueryTextChanged(String query) {
if (!query.equals("")) {
ArrayList<Note> notes = Utilities.getAllSavedNotes(getApplicationContext());
final NoteListAdapter na = new NoteListAdapter(this, R.layout.list_component, notes);
na.getFilter().filter(query);
} else {
ArrayList<Note> notes = Utilities.getAllSavedNotes(getApplicationContext());
final NoteListAdapter na = new NoteListAdapter(this, R.layout.list_component, notes);
}
return false;
}
The other way could be inside the performFiltering() method of the Filter interface implementation. You could also check if the string is empty there, and if so you need to return the full list, without creating a new support one in which you add elements only if certain condition are match.

How to properly implement filterable on listview array adapter

I am working on a note application and i need help with implementing a searchable feature of the note titles of my listview. I have an array adapter class that in which extends filterable and also a Note class that serializes the content.
For now, i have implemented a search bar on my toolbar but whenever i type a letter, the list items just disappears and i get an error afterwards.
Main Activity
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
ArrayAdapter<String> arrayAdapter = (ArrayAdapter<String>) mListNotes.getAdapter();
arrayAdapter.getFilter().filter(newText);
return false;
}
});
NoteAdapter.java
public class NoteAdapter extends ArrayAdapter<Note> implements Filterable{
public static final int WRAP_CONTENT_LENGTH = 50;
public ArrayList<Note> notes;
public NoteAdapter(Context context, int resource, List<Note> objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.view_note_item, null);
}
Note note = getItem(position);
if(note != null) {
TextView title = (TextView) convertView.findViewById(R.id.list_note_title);
TextView date = (TextView) convertView.findViewById(R.id.list_note_date);
TextView content = (TextView) convertView.findViewById(R.id.list_note_content_preview);
title.setText(note.getTitle());
date.setText(note.getDateTimeFormatted(getContext()));
//correctly show preview of the content (not more than 50 char or more than one line!)
int toWrap = WRAP_CONTENT_LENGTH;
int lineBreakIndex = note.getContent().indexOf('\n');
//not an elegant series of if statements...needs to be cleaned up!
if(note.getContent().length() > WRAP_CONTENT_LENGTH || lineBreakIndex < WRAP_CONTENT_LENGTH) {
if(lineBreakIndex < WRAP_CONTENT_LENGTH) {
toWrap = lineBreakIndex;
}
if(toWrap > 0) {
content.setText(note.getContent().substring(0, toWrap) + "...");
} else {
content.setText(note.getContent());
}
} else { //if less than 50 chars...leave it as is :P
content.setText(note.getContent());
}
}
return convertView;
}
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Note> myList = new ArrayList<>();
if (constraint !=null && notes!= null) {
int length = notes.size();
int i = 0;
while (i<length) {
Note item = notes.get(i);
myList.add(item);
i++;
}
filterResults.values = myList;
filterResults.count = myList.size();
}
return null;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notes = (ArrayList<Note>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
public Filter getFilter(){
return filter;
}
}
Note.java
public class Note implements Serializable {
private long mDateTime; //creation time of the note
private String mTitle; //title of the note
private String mContent; //content of the note
public Note(long dateInMillis, String title, String content) {
mDateTime = dateInMillis;
mTitle = title;
mContent = content;
}
public void setDateTime(long dateTime) {
mDateTime = dateTime;
}
public void setTitle(String title) {
mTitle = title;
}
public void setContent(String content) {
mContent = content;
}
public long getDateTime() {
return mDateTime;
}
/**
* Get date time as a formatted string
* #param context The context is used to convert the string to user set locale
* #return String containing the date and time of the creation of the note
*/
public String getDateTimeFormatted(Context context) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"
, context.getResources().getConfiguration().locale);
formatter.setTimeZone(TimeZone.getDefault());
return formatter.format(new Date(mDateTime));
}
public String getTitle() {
return mTitle;
}
public String getContent() {
return mContent;
}
}
log cat
java.lang.NullPointerException: Attempt to read from field 'int android.widget.Filter$FilterResults.count' on a null object reference
at com.app.ben.notetaker.NoteAdapter$1.publishResults(NoteAdapter.java:82)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
What do i need to include in my logic to properly filter the title of the listview items?
You are always returning null from performFiltering() when you should return filterResults. This is in NoteAdapter.java. There may be other things going on but start here.
Edit: It also doesn't look like you are setting notes anywhere, so will will have nothing to filter. You seem to be missing some other functionality, too, but maybe you didn't post everything.
Here is an example of a custom adapter with custom filtering that looks like it has all the pieces. You could use this as a guide.
I hope this helps.

Null pointer Exception in method getItemCount [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am using a list with card view and recyclerview. I have added adapter for the list and added the getItemCount method. I want to add a search function for my list. So I have added a filter too. But when I am typing in the search view I am getting an Exception on return ItemList.size(); this line.. What Am I missing??
Adapter
public class ItemAdapter extends RecyclerView.Adapter<ListViewHolder> implements Filterable{
public ItemsFilter itemFilter;
ArrayList<Item> mStringFilterList;
private ArrayList<Item> ItemList;
private Context context;
private MyItemClickListener mItemClickListener;
private MyItemLongClickListener mItemLongClickListener;
public ItemAdapter(Context context,ArrayList<Item> ItemList) {
this.context= context;
this.ItemList = ItemList;
}
#Override
public ListViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_layout, null);
ListViewHolder mh = new ListViewHolder(v);
return mh;
}
#Override
public void onBindViewHolder(final ListViewHolder ListViewHolder, int i) {
Item Item = ItemList.get(i);
ListViewHolder.textName.setText(Item.getItem_name());
ListViewHolder.textDesc.setText(Item.getItem_desc());
ListViewHolder.textQty.setText(Item.getItem_qty());
ListViewHolder.textName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
return ItemList.size();
}
public class ItemsFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Item> filterList = new ArrayList<Item>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).getItem_name())
.contains(constraint.toString())) {
Item item = new Item(mStringFilterList.get(i)
.getItem_name(), mStringFilterList.get(i)
.getItem_desc(), mStringFilterList.get(i)
.getItem_qty());
filterList.add(item);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
#Override
public void publishResults(CharSequence constraint,
Filter.FilterResults results) {
ItemList = (ArrayList<Item>) results.values;
notifyDataSetChanged();
}
}
#Override
public Filter getFilter() {
// return a filter that filters data based on a constraint
if (itemFilter == null) {
itemFilter = new ItemsFilter();
}
return itemFilter;
}
}
fragment
public class ViewStock extends Fragment implements SearchView.OnQueryTextListener {
final MainActivity act = (MainActivity) this.getActivity();
public ViewStock() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootview = inflater.inflate(R.layout.fragment_view_stock, container, false);
setHasOptionsMenu(true);
act.array_data = new ArrayList<Item>();
// act.listview.setTextFilterEnabled(true);
// act. = new ArrayList<Item>();
// Context mCtx = getActivity().getApplicationContext();
RecyclerView mRecyclerView = (RecyclerView)rootview.findViewById(R.id.my_recycler_view);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(llm);
// ItemAdapter adapter = new ItemAdapter(getActivity(), R.layout.list_item, act.arrayList);
// listview.setAdapter(adapter);
act.db = new DBHandler(getActivity());
ArrayList<Item> item_array_from_db = act.db.Get_items();
for (int i = 0; i < item_array_from_db.size(); i++) {
int idno = item_array_from_db.get(i).getID();
String name = item_array_from_db.get(i).getItem_name();
String desc = item_array_from_db.get(i).getItem_desc();
String qty = item_array_from_db.get(i).getItem_qty();
Item cnt = new Item();
cnt.setID(idno);
cnt.setItem_name(name);
cnt.setItem_desc(desc);
cnt.setItem_qty(qty);
act.array_data.add(cnt);
}
act.db.close();
act.adapter=new ItemAdapter(getActivity(),act.array_data);
mRecyclerView.setAdapter(act.adapter);
return rootview;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.menu_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
act.adapter.getFilter().filter("");
} else {
act.adapter.getFilter().filter(newText.toString());
}
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
}
class
public class Item {
public int id;
public String item_name;
public String item_desc;
public String item_qty;
public Item(){}
public Item(int id, String item_name, String item_desc, String item_qty) {
super();
this.item_name = item_name;
this.item_desc = item_desc;
this.item_qty = item_qty;
}
public Item(String item_name, String item_desc, String item_qty){
this.item_name = item_name;
this.item_desc=item_desc;
this.item_qty = item_qty;
}
public int getID(){
return id;
}
public void setID(int id){
this.id= id;
}
public String getItem_name(){
return item_name;
}
public void setItem_name(String item_name)
{
this.item_name=item_name;
}
public String getItem_desc()
{
return item_desc;
}
public void setItem_desc(String item_desc)
{
this.item_desc=item_desc;
}
public String getItem_qty()
{
return item_qty;
}
public void setItem_qty(String item_qty) {
this.item_qty = item_qty;
}
}
ItemList is getting set to null somewhere. One way to guard against this is to change your getItemCount method to return 0 if the list is null:
int getItemCount(){
return ItemList == null ? 0 : ItemList.size();
}
Just initialize your ItemList like,
private ArrayList<Item> ItemList = new ArrayList<Item>();
Below method not work your app open close again and again.
But above method work for null pointer exception. You should initialize this on recycler view activity.java section.
OR, Add a check in your getItemCount()
#Override
public int getItemCount() {
If (ItemList == null)
return 0;
else
return ItemList.size();
}
EDITED
#Override
public int getItemCount() {
if (ItemList == null)
return 0;
else
return ItemList.size();
}

Categories

Resources