如何在FirebaseUI RecycleView Firestore android中实现搜索

问题描述 投票:1回答:1

这里是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; }

当前代码清除了mSnapshot,并且无法向其中添加过滤的项目,您认为这里有办法吗?

 @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,但是这里没有办法,FirebaseUI适配器非常方便。

java android android-recyclerview google-cloud-firestore recycler-adapter
1个回答
0
投票

您可以像这样执行查询更新

override fun onQueryTextChange(newText: String): Boolean {
            /*perform filtering*/
            Log.d("myItems", "filtering by $newText")
            val originalListOptions = FirestoreRecyclerOptions.Builder<Item>()
                .setQuery(viewModel.query,Item::class.java)
                .setLifecycleOwner(this@ItemListFragment)
                .build()
            val filteredListQuery = viewModel.query.whereGreaterThanOrEqualTo("title",newText)
                .whereLessThanOrEqualTo("title",newText+"\uf8ff")
            val filteredListOptions = FirestoreRecyclerOptions.Builder<Item>()
                .setQuery(filteredListQuery,Item::class.java)
                .setLifecycleOwner(this@ItemListFragment)
                .build()
            if(newText == "")
                mAdapter.updateOptions(originalListOptions)
            else
                mAdapter.updateOptions(filteredListOptions)
            return false
        }

或者,如果您想要更高效,更完整的搜索,请在官方文档中找到那些第三方库,以作为Firestore UI的建议原因,不支持搜索过滤。

您还可以使用带有标准RecyclerView.Adapter的第二类,如上面的代码所示,管理过滤后的列表,然后在片段/活动中替换,仅在搜索过程中,其中包含新的adpater过滤的结果...或类似的内容。

希望会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.