Как реализовать поиск в FirebaseUI RecycleView Firestore для Android - PullRequest
0 голосов
/ 03 ноября 2019

Вот FirestoreRecyclerAdapter,

public class ProfileAdapter extends FirestoreRecyclerAdapter<PersonModel, ProfileAdapter.ProfileHolder> implements ChangeEventListener, LifecycleObserver, Filterable {


    private static final String TAG = "ProfileAdapter";

    private OnItemClickListener mListener;
    private OnItemLongClickListener onItemLongClickListener;
    private Context mContext;
    private FirestoreRecyclerOptions<PersonModel> mOptions;
    private ObservableSnapshotArray<PersonModel> mSnapshots;
    private ArrayList<PersonModel> mSnapshotsTotal;



    public ProfileAdapter(@NonNull FirestoreRecyclerOptions<PersonModel> options, Context context) {
        super(options);
        this.mOptions = options;
        this.mSnapshots = options.getSnapshots();
        this.mContext = context;
        this.mSnapshotsTotal = new ArrayList<>(options.getSnapshots());


        if (options.getOwner() != null) {
            options.getOwner().getLifecycle().addObserver(this);
        }
    }


    @Override
    public int getItemCount() {
        return mSnapshots.isListening(this) ? mSnapshots.size() : 0;
    }


    @Override
    public void onError(@NonNull FirebaseFirestoreException e) {
        super.onError(e);
    }

}



    @NonNull
    @Override
    public ProfileHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_cards, parent, false);
        return new ProfileHolder(view);

    }


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void startListening() {
        if (!mSnapshots.isListening(this)) {
            mSnapshots.addChangeEventListener(this);
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stopListening() {
        mSnapshots.removeChangeEventListener(this);
        notifyDataSetChanged();
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void cleanup(LifecycleOwner source) {
        source.getLifecycle().removeObserver(this);
    }

    @NonNull
    public ObservableSnapshotArray<PersonModel> getSnapshots() {
        return mSnapshots;
    }

    @NonNull
    public PersonModel getItem(int position) {
        return mSnapshots.get(position);
    }


    @Override
    public void onDataChanged() {
        super.onDataChanged();
    }

    /**
     * Re-initialize the Adapter with a new set of options. Can be used to change the query without
     * re-constructing the entire adapter.
     */
    public void updateOptions(@NonNull FirestoreRecyclerOptions<PersonModel> options) {
        // Tear down old options
        boolean wasListening = mSnapshots.isListening(this);
        if (mOptions.getOwner() != null) {
            mOptions.getOwner().getLifecycle().removeObserver(this);
        }
        mSnapshots.clear();
        stopListening();

        // Set up new options
        mOptions = options;
        mSnapshots = options.getSnapshots();
        if (options.getOwner() != null) {
            options.getOwner().getLifecycle().addObserver(this);
        }
        if (wasListening) {
            startListening();
        }
    }




    @Override
    public Filter getFilter() {
        return mFilter;
    }




    private Filter mFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            List<PersonModel> filteredSnapshots = new ArrayList<>();


            if (constraint == null || constraint.length() == 0){
                filteredSnapshots.addAll(mSnapshotsTotal);
            } else {
                String filterPatter = constraint.toString().toLowerCase().trim();

                for (PersonModel item : mSnapshotsTotal){
                    if (item.getName().toLowerCase().contains(filterPatter)){
                        filteredSnapshots.add(item);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredSnapshots;

            return results;


        }





        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {


        mSnapshots.clear();
        mSnapshots.addAll(results.values);
        notifyDataSetChanged();

        }

После получения всех documentSnapshots с использованием данной опции / запроса, как мне тогда показать только те снимки в моем recycleView, которые соответствуют тексту, который я печатаю в searchView здесь-

materialSearchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            profileAdapter.getFilter().filter(newText);
            return false;
        }
    });

}

@Override public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.menu_home, menu);
    MenuItem searchBar = menu.findItem(R.id.action_search);
    materialSearchView.setMenuItem(searchBar);

    return true; }

Текущий код очищает mSnapshots и не может добавить к нему отфильтрованные элементы. Как вы думаете, есть ли способ здесь?

 @Override
        public Filter getFilter() {
            return mFilter;
        }




        private Filter mFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                List<PersonModel> filteredSnapshots = new ArrayList<>();


                if (constraint == null || constraint.length() == 0){
                    filteredSnapshots.addAll(mSnapshotsTotal);
                } else {
                    String filterPatter = constraint.toString().toLowerCase().trim();

                    for (PersonModel item : mSnapshotsTotal){
                        if (item.getName().toLowerCase().contains(filterPatter)){
                            filteredSnapshots.add(item);
                        }
                    }
                }

                FilterResults results = new FilterResults();
                results.values = filteredSnapshots;

                return results;


            }





            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {


            mSnapshots.clear();
            mSnapshots.addAll(results.values);
            notifyDataSetChanged();

            }

Я знаю, что есть Algolia и Elastic Search outтам, но здесь нет пути, адаптер FirebaseUI довольно удобен.

...