Java 如何在FirebaseUI RecycleView Firestore android中实现搜索
这是FirestoreRecyclerAdapterJava 如何在FirebaseUI RecycleView Firestore android中实现搜索,java,android,google-cloud-firestore,android-recyclerview,Java,Android,Google Cloud Firestore,Android Recyclerview,这是FirestoreRecyclerAdapter public class ProfileAdapter extends FirestoreRecyclerAdapter<PersonModel, ProfileAdapter.ProfileHolder> implements ChangeEventListener, LifecycleObserver, Filterable { private static final String TAG = "ProfileA
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();
}
当前代码清除了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();
}
@覆盖
公共过滤器getFilter(){
返回过滤器;
}
专用过滤器mFilter=新过滤器(){
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
List filteredSnapshots=new ArrayList();
if(constraint==null | | constraint.length()==0){
filteredSnapshots.addAll(mSnapshotsTotal);
}否则{
String filterPatter=constraint.toString().toLowerCase().trim();
用于(个人模型项:mSnapshotsTotal){
if(item.getName().toLowerCase().contains(filterPatter)){
filteredSnapshots.add(项目);
}
}
}
FilterResults results=新的FilterResults();
results.values=filteredSnapshots;
返回结果;
}
@凌驾
受保护的void publishResults(CharSequence约束、FilterResults结果){
mSnapshots.clear();
mSnapshots.addAll(results.values);
notifyDataSetChanged();
}
我知道有Algolia和Elastic Search,但这附近没有办法,FirebaseUI适配器非常方便。您可以像这样执行查询更新
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
}
重写onQueryTextChange(newText:String):布尔值{
/*执行过滤*/
Log.d(“myItems”,“按$newText筛选”)
val originalListOptions=FirestoreRecyclerOptions.Builder()
.setQuery(viewModel.query,Item::class.java)
.setLifecycleOwner(this@ItemListFragment)
.build()
val filteredListQuery=viewModel.query.where大于或等于“title”,newText)
.whereLessThanOrEqualTo(“标题”,新文本+“\uf8ff”)
val filteredListOptions=FirestoreRecyclerOptions.Builder()
.setQuery(filteredListQuery,Item::class.java)
.setLifecycleOwner(this@ItemListFragment)
.build()
如果(newText==“”)
mAdapter.updateOptions(原始停止选项)
其他的
mAdapter.updateOptions(filteredListOptions)
返回错误
}
或者,如果您想要更高效、更完整的搜索,在官方文档中,有一些第三方库作为建议,因为Firestore UI不支持搜索过滤
您还可以将第二个类与标准的RecyclerView.Adapter
一起使用,您可以在其中管理筛选列表,然后在片段/活动中,仅在搜索过程中,使用筛选结果中的新适配器替换adpater…或类似的内容
希望这会有帮助
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
}