Recycler view multiple search - java

Currently i can search only one string word. example, I need to search for multiple words i type "nougat,donut" and they show me these two? What i need to put in code for this to work?
DataAdapter.java
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> implements Filterable {
private ArrayList<AndroidVersion> mArrayList;
private ArrayList<AndroidVersion> mFilteredList;
public DataAdapter(ArrayList<AndroidVersion> arrayList) {
mArrayList = arrayList;
mFilteredList = arrayList;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.tv_name.setText(mFilteredList.get(i).getName());
viewHolder.tv_version.setText(mFilteredList.get(i).getVer());
viewHolder.tv_api_level.setText(mFilteredList.get(i).getApi());
}
#Override
public int getItemCount() {
return mFilteredList.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = mArrayList;
} else {
ArrayList<AndroidVersion> filteredList = new ArrayList<>();
for (AndroidVersion androidVersion : mArrayList) {
if (androidVersion.getApi().toLowerCase().contains(charString) || androidVersion.getName().toLowerCase().contains(charString) || androidVersion.getVer().toLowerCase().contains(charString)) {
filteredList.add(androidVersion);
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList<AndroidVersion>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView tv_name,tv_version,tv_api_level;
public ViewHolder(View view) {
super(view);
tv_name = (TextView)view.findViewById(R.id.tv_name);
tv_version = (TextView)view.findViewById(R.id.tv_version);
tv_api_level = (TextView)view.findViewById(R.id.tv_api_level);
}
}
json recycler view
this is search but only for one word

you can try this
if (charString.contains(",")) {
String searchChar[] = charString.split(",");
for (int i = 0; i < searchChar.length; i++) {
if (androidVersion.getApi().toLowerCase().contains(searchChar[i]) || androidVersion
.getName()
.toLowerCase().contains(searchChar[i]) || androidVersion.getVer().toLowerCase()
.contains(searchChar[i])) {
filteredList.add(androidVersion);
}
}
} else {
if (androidVersion.getApi().toLowerCase().contains(charString) || androidVersion.getName()
.toLowerCase().contains(charString) || androidVersion.getVer().toLowerCase()
.contains(charString)) {
filteredList.add(androidVersion);
}
}
replace the code :
if (androidVersion.getApi().toLowerCase().contains(charString) ||
androidVersion.getName().toLowerCase().contains(charString) ||
androidVersion.getVer().toLowerCase().contains(charString)) {
filteredList.add(androidVersion);
}

You need to add some pre-processing to determine if there are multiple values
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String splitter = ",";
final String[] multipleValues = charSequence.toString().split(splitter);
//your null check
List<AndroidVersions> filteredList = new ArrayList()
for (String value : multipleValues) {
filteredList.addAll(internalFilter(mArrayList, value));
}
//the rest of your code
}
private List<AndroidVersions> internalFilter(ArrayList<AndroidVersions> listToFilter, String value) {
List<AndroidVersions> filteredList = new ArrayList()
for (AndroidVersion androidVersion : listToFilter) {
if (androidVersion.getApi().toLowerCase().contains(value)
|| androidVersion.getName().toLowerCase().contains(value)
|| androidVersion.getVer().toLowerCase().contains(value)) {
filteredList.add(androidVersion);
}
}
return filteredList;
}
This code will also work perfectly fine with only 1 value

Related

FIrst dropdown item to be fixed in autoCompleteTextView

I created an app that has an autoCompleteTextView in order to allow the user to perform search queries.
Once they start typing, a dropdown appears and offers the results.
Now, I would like to make the first item to be fixed and unscrollable which will say something like: can't find? add manually.
How can I make the first item in the suggested dropdown list to be fixed and appear always?
My code for the adapter is:
public class AutoCompleteImageAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> fullList;
private ArrayList<String> mOriginalValues;
private ArrayFilter mFilter;
private Boolean noResults;
private TextView tv_name;
private ImageView im_cover;
private List<String> url, id;
private StorageReference storageRef;
private FirebaseFirestore db;
public AutoCompleteImageAdapter(Context context, int resource, int textViewResourceId, List<String> objects, List<String> url, List<String> id, Boolean noResult) {
super( context, resource, textViewResourceId, objects );
fullList = (ArrayList<String>) objects;
mOriginalValues = new ArrayList<String>( fullList );
noResults = noResult;
this.url = url;
this.id = id;
}
#Override
public int getCount() {
if (fullList.size() > 40) {
return 40;
} else {
return fullList.size();
}
}
#Override
public String getItem(int position) {
return fullList.get( position );
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
db = FirebaseFirestore.getInstance();
storageRef = FirebaseStorage.getInstance().getReference();
View row = convertView;
String id = this.id.get( position );
LayoutInflater inflater = LayoutInflater.from( getContext() );
if (row == null) {
row = inflater.inflate( R.layout.item_auto_add, parent, false );
}
tv_name = (TextView) row.findViewById( R.id.item_drop );
tv_name.setText( fullList.get( position ) );
im_cover = row.findViewById( R.id.iv_itemCover );
String Url = url.get( position );
if (id.length() > AppConstants.UPLOADED_item_LENGTH) {
storageRef.child( "/itemCovers/" + Url + "/" + Url + ".jpg" ).getDownloadUrl().addOnSuccessListener( new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.with( parent.getContext() ).load( uri ).resize( 110, 160 ).into( im_cover );
}
} ).addOnFailureListener( new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.d( "ERROR", exception + "" );
}
} );
} else {
Picasso.with( parent.getContext() ).load( Uri.parse( Url ) ).error( R.drawable.ic_nocover ).resize( 110, 160 ).into( im_cover );
}
return row;
}
#Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ArrayFilter();
}
return mFilter;
}
private class ArrayFilter extends Filter {
private Object lock;
#Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (lock) {
mOriginalValues = new ArrayList<String>( fullList );
}
}
if (prefix == null || prefix.length() == 0) {
synchronized (lock) {
ArrayList<String> list = new ArrayList<String>( mOriginalValues );
results.values = list;
results.count = list.size();
}
} else {
final String prefixString = prefix.toString().toLowerCase();
ArrayList<String> values = mOriginalValues;
int count = values.size();
ArrayList<String> newValues = new ArrayList<String>( count );
for (int i = 0; i < count; i++) {
String item = values.get( i );
if (item.toLowerCase().contains( prefixString )) {
newValues.add( item );
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.values != null) {
fullList = (ArrayList<String>) results.values;
} else {
fullList = new ArrayList<String>();
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
public void clear() {
if (fullList != null) {
fullList.clear();
notifyDataSetChanged();
}
}
}
Thank you
add it as the first item to your List objects before you pass it to the adapter and then populate the list with data you wanna show as search result so that element 0 is always "can't find? add manually". This way it is always there and the other items change.
and then in the item click listener you can check for the item text and act accordingly if it matches "can't find? add manually".
I think the code below solves your requirement to some level. Do try and comment.
<AutoCompleteTextView
android:layout_below="#+id/edit_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/project"
android:id="#+id/edit_project"
android:completionThreshold="0"
android:completionHint="#string/message"
android:inputType="text"
/>
This code gives a hint at the bottom of the list to the user.

Delete correct items in recyclerview during search

I use a recyclerview which I modify thanks to Diffutils. Unfortunately, when I filter my recyclerview and delete items, the index of the deleted items does not match that of my list.
For instance, if I have 3 items: [a, ab,abc] with the index (0,1,2) and I filter with the word "ab", the newly displayed items are [ab, abc] with the index (0,1) so when I try to delete items from the recyclerView, index are wrong.
This is a part of my recycler code
public class NoteListAdapter extends RecyclerView.Adapter<NoteListAdapter.NoteListViewHolder> implements Filterable {
private List<Note> noteList;
private List<Note> noteListFull;
private NoteEventListener listener;
private CustomFilter filter;
public NoteListAdapter(List<Note> noteList, NoteEventListener noteEventListener) {
this.noteList = noteList;
this.noteListFull = noteList;
this.listener = noteEventListener;
}
public void updateList(List<Note> newList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtils(this.noteList, newList));
noteList.clear();
noteList.addAll(newList);
diffResult.dispatchUpdatesTo(this);
}
public void insertList(List<Integer> index, List<Note> newList) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtils(this.noteList, newList));
for (int i =0; i < newList.size(); i++)
noteList.add(index.get(i), newList.get(i));
diffResult.dispatchUpdatesTo(this);
}
#Override
public void onBindViewHolder(#NonNull final NoteListViewHolder holder, int position) {
final Note note = noteList.get(position);
if (note != null) {
holder.itemView.setOnClickListener(v -> listener.onNoteClick(position, note));
holder.itemView.setOnLongClickListener(v -> {
listener.onNoteLongClick(position, note);
return true;
});
}
}
#Override
public Filter getFilter() {
if(filter == null)
filter = new CustomFilter();
return filter;
}
class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint == null || constraint.length() == 0) {
filterResults.values = noteListFull;
filterResults.count = noteListFull.size();
}
else {
String pattern = constraint.toString().toLowerCase();
List<Note> filters = new ArrayList<>();
for(Note item: noteListFull) {
if (item.getTitle().toLowerCase().contains(pattern)) {
Note n = new Note(item.getTitle(), item.getContent());
filters.add(n);
}
}
filterResults.values = filters;
filterResults.count = filters.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
noteList = (List) results.values;
notifyDataSetChanged();
}
}
}
And this is my code when I delete an item:
private void delete_note() {
// Position of all selected items ready to be deleted (but with wrong index)
List<Integer> selectedItems = noteListAdapter.getSelectedItems();
List<Note> temp = new ArrayList<>(notes);
List<Note> deletedItems = selectedItems.stream().map(notes::get).collect(Collectors.toList());
temp.removeAll(deletedItems);
noteListAdapter.updateList(temp);
}

Parsing a JSON and extracting items with condition

My question is similar to this Implementing Search Filter in Adapter Class which parses a json array (without using pojo)
but I would like to try to struggle the problem differently. I have a list of elements that must be filtered based on a condition and once this condition is verified, I want to retrieve the elements that verify it from the json array. In this example, I filtered the elements based on their name, and in the setContentValue () I would set the code and the hex string taking only those elements that have that name, otherwise during filtering the name has a different index from the code and the hex strings. How could I do that?
Fragment
public class ColorViewFragment extends Fragment {
private RecyclerView recyclerView;
private JSONArray json;
private ColorListAdapter adapter;
private EditText editColor;
#Nullable #Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.color_list, container, false);
this.recyclerView = view.findViewById(R.id.recyclerView);
/*
try {
this.recyclerView.setAdapter(new ColorListAdapter(this.json));
} catch (JSONException e) {
e.printStackTrace();
}
*/
try {
adapter = new ColorListAdapter(json);
} catch (JSONException e) {
e.printStackTrace();
}
recyclerView.setAdapter(adapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
this.recyclerView.setLayoutManager(layoutManager);
//
editColor = view.findViewById(R.id.editText);
editColor.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
ColorViewFragment.this.adapter.getFilter().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
return view;
}
public void setJSON(JSONArray newJson){
this.json = newJson;
}
Adapter
public class ColorListAdapter extends RecyclerView.Adapter implements Filterable {
private JSONArray colorList;
private List<String> colorListFiltered = new ArrayList<String>();
public ColorListAdapter(JSONArray json) throws JSONException {
super();
if (json != null) {
this.colorList = json;
for (int i=0;i<json.length();i++){
//colorListFiltered.add((colorList.getString(i)));
colorListFiltered.add(json.getJSONObject(i).getString("Name"));
}
}
}
#Override
public Filter getFilter() {
return new colorFilter();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_color_view, viewGroup, false);
return new ColorListHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
try {
((ColorListHolder) viewHolder).setContentValue(i);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return this.colorListFiltered.size();
}
private class ColorListHolder extends RecyclerView.ViewHolder {
private TextView colorCodeText;
private TextView colorNameText;
private CardView imageView;
public ColorListHolder(#NonNull View itemView) {
super(itemView);
this.colorCodeText = itemView.findViewById(R.id.colorCode_text);
this.colorNameText = itemView.findViewById(R.id.colorName_text);
this.imageView = itemView.findViewById(R.id.colorView);
}
public void setContentValue(int index) throws JSONException {
this.colorNameText.setText(colorListFiltered.get(index));
//this.colorNameText.setText(((JSONObject) colorList.get(index)).getString("Name"));
this.colorCodeText.setText(((JSONObject) colorList.get(index)).getString("ColorCode"));
this.imageView.setCardBackgroundColor(Color.parseColor(((JSONObject) colorList.get(index)).getString("HexString")));
}
}
public class colorFilter extends Filter{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults Result = new FilterResults();
// if constraint is empty return the original names
if(constraint.length() == 0 ) {
ArrayList<String> arrColorList = new ArrayList<>();
for (int i = 0; i < colorList.length(); i++) {
try {
arrColorList.add(colorList.getJSONObject(i).getString("Name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
Result.values = arrColorList;
Result.count = arrColorList.size();
return Result;
}
/*if(constraint.length() == 0 ){
Result.values = colorList;
Result.count = colorList.length();
return Result;*/
else {
List<String> Filtered_Names = new ArrayList<String>();
String filterString = constraint.toString().toLowerCase();
String filterableString = "";
for (int i = 0; i < colorList.length(); i++) {
try {
filterableString = (colorList.getJSONObject(i)).getString("Name");
} catch (JSONException e) {
e.printStackTrace();
}
if (filterableString.toLowerCase().contains(filterString)) {
Filtered_Names.add(filterableString);
}
}
Result.values = Filtered_Names;
Result.count = Filtered_Names.size();
return Result;
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
colorListFiltered = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
I am near solution, list loads and get filtered, but when I delete word, I get a ClassCastException: String cannot be cast to JSONObject (in setContentValue).
public class ColorListAdapter extends RecyclerView.Adapter implements Filterable {
private List<JSONObject> colorList = new ArrayList<JSONObject>();
private List<JSONObject> colorListFiltered = new ArrayList<JSONObject>();
public ColorListAdapter(JSONArray json) throws JSONException {
super();
if (json != null) {
for(int i=0; i<json.length(); i++) {
JSONObject jsonObj = json.getJSONObject(i);
colorList.add(jsonObj);
colorListFiltered = colorList;
}
}
}
#Override
public Filter getFilter() {
return new colorFilter();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_color_view, viewGroup, false);
return new ColorListHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
try {
((ColorListHolder) viewHolder).setContentValue(i);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return this.colorListFiltered.size();
}
private class ColorListHolder extends RecyclerView.ViewHolder {
private TextView colorNameText;
private TextView colorCodeText;
private CardView imageView;
public ColorListHolder(#NonNull View itemView) {
super(itemView);
this.colorCodeText = itemView.findViewById(R.id.colorCode_text);
this.colorNameText = itemView.findViewById(R.id.colorName_text);
this.imageView = itemView.findViewById(R.id.colorView);
}
public void setContentValue(final int index) throws JSONException {
this.colorNameText.setText(colorListFiltered.get(index).getString("Name"));
this.colorCodeText.setText(colorListFiltered.get(index).getString("ColorCode"));
this.imageView.setCardBackgroundColor(Color.parseColor(colorListFiltered.get(index).getString("HexString")));
}
}
//filtro su Name
public class colorFilter extends Filter{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults Result = new FilterResults();
// if constraint is empty return the original names
if(constraint.length() == 0 ) {
ArrayList<String> arrNameList = new ArrayList<>();
for (int i = 0; i < colorList.size(); i++) {
try {
arrNameList.add(colorList.get(i).getString("Name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
Result.values = arrNameList;
Result.count = arrNameList.size();
return Result;
}
else {
List<JSONObject> Filtered_Names = new ArrayList<JSONObject>();
String filterString = constraint.toString().toLowerCase();
String filterableString = "";
for (int i = 0; i < colorList.size(); i++) {
try {
filterableString = (colorList.get(i)).getString("Name");
} catch (JSONException e) {
e.printStackTrace();
}
if (filterableString.toLowerCase().contains(filterString)) {
Filtered_Names.add(colorList.get(i));
}
}
Result.values = Filtered_Names;
Result.count = Filtered_Names.size();
return Result;
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
colorListFiltered = (ArrayList<JSONObject>) results.values;
notifyDataSetChanged();
}
}
}
You use colorListFiltered for names but you use colorList for hex codes in setContentValue. First two lists are same but when you filter colorListFiltered they are getting different.
Change this,
private JSONArray colorList;
private List<String> colorListFiltered = new ArrayList<String>();
to
private List<JSONObject> colorList = new ArrayList<JSONObject>();
private List<JSONObject> colorListFiltered = new ArrayList<JSONObject>();
and your performFiltering
List<JSONObject> Filtered_Names = new ArrayList<JSONObject>();
String filterString = constraint.toString().toLowerCase();
String filterableString = "";
for (int i = 0; i < colorList.size(); i++) {
try {
filterableString = (colorList.get(i)).getString("Name");
} catch (JSONException e) {
e.printStackTrace();
}
if (filterableString.toLowerCase().contains(filterString)) {
Filtered_Names.add(colorList.get(i));
}
}
setContentValue:
public void setContentValue(int index) throws JSONException {
this.colorNameText.setText(colorListFiltered.get(index).getString("Name"));
this.colorCodeText.setText(colorListFiltered.get(index).getString("ColorCode"));
this.imageView.setCardBackgroundColor(Color.parseColor(colorListFiltered.get(index).getString("HexString"));
}

Filtering ListView via Spinner using JSON response

So I have this fun little list adapter I'm trying to figure out, in addition to Android/Java as a whole. It started with just compiling a simple list of RFID tags picked up by a scanner. The API that came with the scanner made that part pretty easy. It later evolved into fetching JSON objects associated with the tags the scanner would pick up via a URL that needed to be built using the tag ID itself.
Fast forward to today, I'm now trying to figure out a way to filter the finished list items, but I need it be done by the 'status' of the tag; not the actual 10-digit string, 'tagTitle'. Unfortunately, the working spinner filter I have set up now only does it by 'tagTitle' because I can't figure out how to access the other two TextViews to use them as a constraint instead. However, the array used by the spinner is populated with all the possible status we have in our system. So obviously any filter selection I pick, the list goes blank.
With that said, any help that'll get me to Point-B would be greatly appreciated. If there's any more information I should've included in this, please let me know. Thanks.
public class rfid_status extends UgiUiActivity implements
UgiInventoryDelegate,
UgiInventoryDelegate.InventoryDidStopListener,
UgiInventoryDelegate.InventoryTagFoundListener {
public UgiRfidConfiguration rfidConfig;
public EPCAdapter epcAdapter;
public List<UgiTag> tagArray = new ArrayList<>();
public RequestQueue rQ;
public Spinner tagSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rfid_status);
ListView tagListView = (ListView) findViewById(R.id.tagList);
String[] statStrings = {
"",
"In",
"Filled",
"Out",
"Repair",
"Lost",
"QC",
"Missing",
"Sold",
"In Transfer"
};
ArrayAdapter<String> statusArray = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, statStrings);
tagSearch = (Spinner) findViewById(R.id.tagSearch);
tagSearch.setAdapter(statusArray);
tagSearch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String constraint = parent.getItemAtPosition(position).toString();
epcAdapter.getFilter().filter(constraint);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Do Nothing
}
});
this.setDisplayDialogIfDisconnected(true);
UgiTitleView titleView = (UgiTitleView) findViewById(R.id.status_title);
titleView.setTheTitle(getResources().getString(R.string.status_title));
this.configureTitleViewNavigation(titleView);
titleView.setBatteryStatusIndicatorDisplayVersionInfoOnTouch(true);
titleView.setUseBackgroundBasedOnUiColor(true);
titleView.setThemeColor(ContextCompat.getColor(this, msq_black));
titleView.setTextColorOnThemeColor(ContextCompat.getColor(this, msq_red));
titleView.setDisplayWaveAnimationWhileScanning(true);
rQ = Volley.newRequestQueue(this);
rfidConfig = UgiRfidConfiguration.INVENTORY_SHORT_RANGE;
epcAdapter = new EPCAdapter(this);
tagListView.setAdapter(epcAdapter);
updateUI();
}
public class EPCAdapter extends BaseAdapter implements Filterable {
rfid_status rfidStatus;
List<UgiTag> origTags;
EPCAdapter(rfid_status rfidStatus) {
super();
this.rfidStatus = rfidStatus;
}
class TagHolder {
TextView tagNumber, tagDetails, tagStatus;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public int getCount() {
return tagArray.size();
}
#Override
public Object getItem(int position) {
return position < tagArray.size() ? tagArray.get(position) : null;
}
#Override
public long getItemId(int position) {
return position < tagArray.size() ? tagArray.get(position).getEpc().hashCode() : 0;
}
#SuppressLint("InflateParams")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final TagHolder tagHolder;
final UgiTag ugiTag = tagArray.get(position);
final String tagTitle = ugiTag.toString().substring(14);
Uri.Builder jsonBuild = new Uri.Builder();
jsonBuild.scheme("http").authority("thirdstreamv2").appendPath("utilities").appendPath("HandheldGreenScreen").appendQueryParameter("assetid", tagTitle);
String jsonURL = jsonBuild.build().toString();
if (convertView == null) {
convertView = LayoutInflater.from(rfid_status.this).inflate(R.layout.tag_row, null);
tagHolder = new TagHolder();
tagHolder.tagNumber = (TextView) convertView.findViewById(R.id.tagHere);
tagHolder.tagStatus = (TextView) convertView.findViewById(R.id.statHere);
tagHolder.tagDetails = (TextView) convertView.findViewById(R.id.descHere);
convertView.setTag(tagHolder);
} else {
tagHolder = (TagHolder) convertView.getTag();
}
JsonObjectRequest jObj = new JsonObjectRequest(Request.Method.GET, jsonURL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String displayIf = response.getString("display");
if (!displayIf.equals("true")) {
tagArray.remove(ugiTag);
notifyDataSetChanged();
} else {
tagHolder.tagNumber.setText(tagTitle);
tagHolder.tagStatus.setText(response.getString("status"));
// I need to filter by the above somehow...
tagHolder.tagDetails.setText(response.getString("description"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
rQ.add(jObj);
return convertView;
}
#Override
public Filter getFilter() {
return new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
tagArray = (List<UgiTag>) results.values;
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<UgiTag> filteredTags = new ArrayList<>();
constraint = constraint.toString();
if (origTags == null) {
origTags = new ArrayList<>(tagArray);
}
if (constraint.length() == 0) {
results.count = origTags.size();
results.values = origTags;
} else {
for (int position = 0; position < origTags.size(); position++) {
UgiTag ugiTag = origTags.get(position);
String tagString = ugiTag.toString().substring(14);
if (tagString.contains(constraint)) {
filteredTags.add(ugiTag);
}
}
results.count = filteredTags.size();
results.values = filteredTags;
}
return results;
}
};
}
}
Never mind, answered it myself. I trashed my old array and created a new one using a custom object I put together to store the JSON responses instead of listing only the RFID tags (UgiTag). With the values being in the object, I can now access them within the filter and use it as a constraint.
public class EPCAdapter extends BaseAdapter implements Filterable {
rfid_status rfidStatus;
List<TagInfo> origTags = null;
EPCAdapter(rfid_status rfidStatus) {
super();
this.rfidStatus = rfidStatus;
}
class TagHolder {
TextView tagNumber, tagDetails, tagStatus;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public int getCount() {
return tagList.size();
}
#Override
public Object getItem(int position) {
return position < tagList.size() ? tagList.get(position) : null;
}
#Override
public long getItemId(int position) {
return position < tagList.size() ? tagList.get(position).hashCode() : 0;
}
#SuppressLint("InflateParams")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final TagInfo tagItem = tagList.get(position);
final String tagTitle = tagItem.getUgiTag().toString().substring(14);
final TagHolder tagHolder;
Uri.Builder jsonBuild = new Uri.Builder();
jsonBuild.scheme("http").authority("thirdstreamv2").appendPath("utilities").appendPath("HandheldGreenScreen").appendQueryParameter("assetid", tagTitle);
String jsonURL = jsonBuild.build().toString();
if (convertView == null) {
convertView = LayoutInflater.from(rfid_status.this).inflate(R.layout.tag_row, null);
tagHolder = new TagHolder();
tagHolder.tagNumber = (TextView) convertView.findViewById(R.id.tagHere);
tagHolder.tagStatus = (TextView) convertView.findViewById(R.id.statHere);
tagHolder.tagDetails = (TextView) convertView.findViewById(R.id.descHere);
convertView.setTag(tagHolder);
} else {
tagHolder = (TagHolder) convertView.getTag();
}
JsonObjectRequest jObj = new JsonObjectRequest(Request.Method.GET, jsonURL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
tagItem.setTagStatus(response.getString("status"));
tagItem.setTagDescription(response.getString("description"));
tagItem.setTagDisplay(response.getString("display"));
tagHolder.tagNumber.setText(tagTitle);
tagHolder.tagStatus.setText(tagItem.getTagStatus());
tagHolder.tagDetails.setText(tagItem.getTagDescription());
if (!tagItem.getTagDisplay().equals("true")) {
tagList.remove(tagItem);
notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
rQ.add(jObj);
return convertView;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<TagInfo> filteredTags = new ArrayList<>();
constraint = constraint.toString();
if (origTags == null) {
origTags = new ArrayList<>(tagList);
}
if (constraint.length() == 0) {
results.count = origTags.size();
results.values = origTags;
} else {
for (int position = 0; position < origTags.size(); position++) {
TagInfo origPos = origTags.get(position);
String tagString = origPos.getTagStatus();
if (tagString.contains(constraint)) {
filteredTags.add(origPos);
}
}
results.count = filteredTags.size();
results.values = filteredTags;
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
tagList = (List<TagInfo>) results.values;
notifyDataSetChanged();
}
};
}
}

Using Checkbox and Filterable in RecycleView Android

I'm creating a project, that uses a webservice to fetch the number of departments and there names and creates dynamic checkboxs.
Then I'm using filterable to filter the adapter , by checking from sharedpreferences if the checkbox is checked if not checked I try to hide it from the adapter
(TicketsActivity):
for (int i=0;i<filterList.size();i++) {
if (!getFromSP(filterList.get(i) + i)) {
mAdapter.getFilter("Department").filter(filterList.get(i).toLowerCase());
}
}
and afther that
if (recyclerView.getAdapter() == null) {
mAdapter.notifyItemRangeInserted(0,ticketList.size()-1);
recyclerView.setAdapter(mAdapter);
} else {
recyclerView.getAdapter().notifyItemRangeInserted(0,ticketList.size()-1);
}
And in my custom Adapter
(TicketsAdapter):
public Filter getFilter(final String type) {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
ticketListFiltered = ticketList;
} else if (type.equals("Search")) {
List<Ticket> filteredList = new ArrayList<>();
for (Ticket row : ticketList) {
if (row.getTitle().toLowerCase().contains(charSequence) || row.getDate().toLowerCase().contains(charSequence) || row.getPriority().toLowerCase().contains(charSequence)) {
filteredList.add(row);
}
}
ticketListFiltered = filteredList;
} else {
List<Ticket> filteredList;
filteredList = ticketList;
for (Ticket row : ticketList) {
if (row.getDepartment().toLowerCase().contains(charSequence)) {
filteredList.remove(row);
}
}
ticketListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values =ticketListFiltered;
return filterResults;
}
#Override
public int getItemCount() {
return ticketListFiltered == null ? 0 : ticketListFiltered.size();
}
However this throws an Exception on 'int java.util.List.size()' getItemCount, if i change the filteredList.remove(row) to filteredList.add(row) it will work find,but i need to remove from the adapter rows with "unchecked" department.But for some reason instead of filtering the adapter, its actualy deleting rows direcly of the adapter. I can't find what i'm doing wrong.
Btw this works fine with SearchView

Categories

Resources