How do I filter data in a scope adapter?
I am facing a problem with filtering data in a scope adapter. I am creating a searchview to find data by filtering the data in realm adapter.
My code for implementing searchview
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
Log.e("Filter ","Filtering");
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(item,
new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
adapter.setFilter(realmPhonecallList);
Log.e("Filter 1","Filtering");
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
}
@Override
public boolean onQueryTextSubmit(String newText) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
final List<RealmPhoneCallLogs> filteredModelList = filter(realmPhonecallList, newText);
Log.e("Filter 2","Filtering" + newText);
adapter.setFilter(filteredModelList);
Log.e("Filter 3","Filtering" + filteredModelList);
return true;
}
private List<RealmPhoneCallLogs> filter(List<RealmPhoneCallLogs> models, String query) {
query = query.toLowerCase();
final List<RealmPhoneCallLogs> filteredModelList = new ArrayList<>();
for (RealmPhoneCallLogs model : models) {
final String text = model.getNumber().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
Log.e("Filter 4","Filtering" + filteredModelList);
return filteredModelList;
}
My interface adapter implementation
private class MyNamesAdapter extends RealmBaseAdapter<RealmPhoneCallLogs> {
List<RealmPhoneCallLogs> filter;
public MyNamesAdapter(OrderedRealmCollection<RealmPhoneCallLogs> data) {
super(data);
this.filter = data;
}
public class ViewHolder {
TextView number;
TextView callType;
TextView startTime;
TextView contactName;
TextView callDuration;
TextView fileSize;
ImageView contactPhoto;
ImageView callSymbol;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final RealmPhoneCallLogs realmPhoneCallLogs = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.calllog_layout, parent, false);
viewHolder.number = (TextView) convertView.findViewById(R.id.missedNumber);
viewHolder.startTime = (TextView) convertView.findViewById(R.id.missedStartTime);
viewHolder.contactName = (TextView) convertView.findViewById(R.id.missedContactName);
viewHolder.callDuration = (TextView) convertView.findViewById(R.id.missedCallDuration);
viewHolder.fileSize = (TextView) convertView.findViewById(R.id.missedFileSize);
viewHolder.contactPhoto = (ImageView) convertView.findViewById(R.id.missedImage);
viewHolder.callSymbol = (ImageView) convertView.findViewById(R.id.callSymbol);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (adapterData != null) {
viewHolder.number.setText(realmPhoneCallLogs.getNumber());
viewHolder.contactName.setText(getContactName(realmPhoneCallLogs.getNumber()));
viewHolder.callDuration.setText(getTime(realmPhoneCallLogs.getCallDuration()));
viewHolder.startTime.setText(realmPhoneCallLogs.getStartTime());
viewHolder.contactPhoto.setImageBitmap(getContactsImage(realmPhoneCallLogs.getNumber()));
String path = new String(Environment.getExternalStorageDirectory() + "/NewCallLogs/" + realmPhoneCallLogs.getCallRecords());
File file = new File(path);
String size;
long filesize = file.length();
long fileSizeInKB = filesize / 1024;
long fileSizeInMB = fileSizeInKB / 1024;
if(fileSizeInKB >=1024){
size= fileSizeInMB + " Mb";
}else {
size = fileSizeInKB + " Kb";
}
if(!size.isEmpty()){
viewHolder.fileSize.setText(size);
}else{
viewHolder.fileSize.setText(0);
}
if (realmPhoneCallLogs.getCallType().equals("I")) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_received);
} else if (realmPhoneCallLogs.getCallType().equals("O")) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_made);
} else if (realmPhoneCallLogs.getCallStatus().equals("UA")) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_missed);
}
return convertView;
}
return convertView;
}
public void setFilter( List<RealmPhoneCallLogs> filtedData) {
filter = new ArrayList<>();
filter.addAll(filtedData);
notifyDataSetChanged();
}
}
Please help me how to filter data in a field.
+3
source to share
2 answers
public void setFilter( List<RealmPhoneCallLogs> filtedData) {
filter = new ArrayList<>(); // <-- WRONG
filter.addAll(filtedData); // <-- WRONG
private List<RealmPhoneCallLogs> filter(List<RealmPhoneCallLogs> models, String query) {
query = query.toLowerCase();
final List<RealmPhoneCallLogs> filteredModelList = new ArrayList<>(); // <-- WRONG
for (RealmPhoneCallLogs model : models) { // <-- WRONG
final String text = model.getNumber().toLowerCase();
if (text.contains(query)) { // <-- WRONG: should be Realm query
Instead, you need to do
// from https://stackoverflow.com/a/33818311/2413303
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
adapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (searchView.getQuery().length() == 0) {
adapter.getFilter().filter("");
}
return false;
}
});
Then, as in the linked answer
private class MyNamesAdapter
extends RealmBaseAdapter<RealmPhoneCallLogs>
implements Filterable {
public MyNamesAdapter(OrderedRealmCollection<RealmPhoneCallLogs> data) {
super(data);
}
public class ViewHolder {
TextView number;
TextView callType;
TextView startTime;
TextView contactName;
TextView callDuration;
TextView fileSize;
ImageView contactPhoto;
ImageView callSymbol;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final RealmPhoneCallLogs realmPhoneCallLogs = getItem(position);
ViewHolder viewHolder;
if(convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.calllog_layout, parent, false);
viewHolder.number = (TextView) convertView.findViewById(R.id.missedNumber);
viewHolder.startTime = (TextView) convertView.findViewById(R.id.missedStartTime);
viewHolder.contactName = (TextView) convertView.findViewById(R.id.missedContactName);
viewHolder.callDuration = (TextView) convertView.findViewById(R.id.missedCallDuration);
viewHolder.fileSize = (TextView) convertView.findViewById(R.id.missedFileSize);
viewHolder.contactPhoto = (ImageView) convertView.findViewById(R.id.missedImage);
viewHolder.callSymbol = (ImageView) convertView.findViewById(R.id.callSymbol);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if(adapterData != null) {
viewHolder.number.setText(realmPhoneCallLogs.getNumber());
viewHolder.contactName.setText(getContactName(realmPhoneCallLogs.getNumber()));
viewHolder.callDuration.setText(getTime(realmPhoneCallLogs.getCallDuration()));
viewHolder.startTime.setText(realmPhoneCallLogs.getStartTime());
viewHolder.contactPhoto.setImageBitmap(getContactsImage(realmPhoneCallLogs.getNumber()));
String path = new String(Environment.getExternalStorageDirectory() + "/NewCallLogs/" + realmPhoneCallLogs
.getCallRecords());
File file = new File(path);
String size;
long filesize = file.length();
long fileSizeInKB = filesize / 1024;
long fileSizeInMB = fileSizeInKB / 1024;
if(fileSizeInKB >= 1024) {
size = fileSizeInMB + " Mb";
} else {
size = fileSizeInKB + " Kb";
}
if(!size.isEmpty()) {
viewHolder.fileSize.setText(size);
} else {
viewHolder.fileSize.setText(0);
}
if("I".equals(realmPhoneCallLogs.getCallType())) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_received);
} else if("O".equals(realmPhoneCallLogs.getCallType())) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_made);
} else if("UA".equals(realmPhoneCallLogs.getCallStatus())) {
viewHolder.callSymbol.setImageResource(R.mipmap.call_missed);
}
return convertView;
}
return convertView;
}
// filtering
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
if(text == null || "".equals(text)) {
updateData(realm.where(RealmPhoneCallLogs.class).findAllSorted("id");
} else {
updateData(realm.where(RealmPhoneCallLogs.class)
.contains("number", text, Case.INSENSITIVE)
.findAllSorted("id"));
}
}
public Filter getFilter() {
return new MyNamesFilter(this);
}
private class MyNamesFilter
extends Filter {
private final MyNamesAdapter adapter;
private MyNamesFilter(MyNamesAdapter adapter) {
super();
this.adapter = adapter;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filterResults(constraint.toString());
}
}
}
For Realm filtering, you can also check the official documentation for requests .
+5
source to share
Here is an example of a Filterable RecyclerView with Realm:
how to implement filtering in RealmRecyclerViewAdapter
Here is the topic of the topic:
https://github.com/realm/realm-java/issues/646
+1
source to share