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


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







All Articles