Android 如何在使用Firestore时为RecyclerView添加搜索过滤器?
所以,我正在尝试创建一个显示作者列表(图片、姓名、简历)的应用程序,问题是我在实现搜索功能时遇到了问题。我使用了Android 如何在使用Firestore时为RecyclerView添加搜索过滤器?,android,firebase,android-recyclerview,google-cloud-firestore,firebaseui,Android,Firebase,Android Recyclerview,Google Cloud Firestore,Firebaseui,所以,我正在尝试创建一个显示作者列表(图片、姓名、简历)的应用程序,问题是我在实现搜索功能时遇到了问题。我使用了RecyclerView的使用指南 代码:MainActivity public class MainActivity extends AppCompatActivity { private FirebaseFirestore db; private FirestoreRecyclerAdapter adapter; private LinearLayoutManager linea
RecyclerView
的使用指南
代码:MainActivity
public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db;
private FirestoreRecyclerAdapter adapter;
private LinearLayoutManager linearLayoutManager;//nodrosina kada veida recycle attelos
private List<Klasiki> list;
@BindView(R.id.imageRecycleView)
RecyclerView klasikiList; //tas pats kas find by ID
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
klasikiList.setLayoutManager(linearLayoutManager);
db = FirebaseFirestore.getInstance();
getList();
}
//atgriez ierakstus no datubazes un nodrosina atteloshanu recycle view
private void getList(){
Query query = db.collection("klasiki");
FirestoreRecyclerOptions<Klasiki> response = new FirestoreRecyclerOptions.Builder<Klasiki>()
.setQuery(query, Klasiki.class)
.build();
adapter = new FirestoreRecyclerAdapter<Klasiki, klasikiHolder>(response) {
@Override
protected void onBindViewHolder(final klasikiHolder holder, int position, final Klasiki model) {
holder.name.setText(model.getName());
holder.shortBio.setText(model.getShortBio());
Glide.with(getApplicationContext()).load(model.getImage()).into(holder.image);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, BioActivity.class);
//Parnes mainigos uz bio activity
Bundle extras = new Bundle();
extras.putString("imageInfo", model.getImage());
extras.putString("nameInfo", model.getName());
extras.putString("bioInfo", model.getFullBio());
intent.putExtras(extras);
startActivity(intent);
}
});
}
@Override
public klasikiHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.klasiki_layout, parent, false);
return new klasikiHolder(view);
} //nodrosina jauna ieraksta returnu
@Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
adapter.notifyDataSetChanged();
klasikiList.setAdapter(adapter);
}
//izsauc mainigos
public class klasikiHolder extends RecyclerView.ViewHolder{
@BindView(R.id.name)
TextView name;
@BindView(R.id.klasikiImage)
ImageView image;
@BindView(R.id.shortBio)
TextView shortBio;
public klasikiHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
我想我必须使用除FirestoreRecyclerOptions之外的其他RecyclerView
选项,但我不确定,这对android编程来说真的是个新手。:)
更新:
所以我做了这样的东西:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
// Retrieve the SearchView and plug it into SearchManager
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String text) {
querySearch = db.collection("klasiki").whereEqualTo("name", text);
if (!text.trim().isEmpty()){
getList(querySearch);
adapter.startListening();
}
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText.trim().isEmpty()){
getList(queryFinal);
adapter.startListening();
}
return false;
}
});
return true;
}
public class Klasiki {
private String name, image, shortBio, fullBio;
public Klasiki( ){}
public Klasiki(String name, String image, String shortBio, String fullBio) {
this.name = name;
this.image = image;
this.shortBio = shortBio;
this.fullBio = fullBio;
}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getImage() {return image;}
public void setImage(String image) {this.image = image;}
public String getShortBio() {return shortBio;}
public void setShortBio(String shortBio) {this.shortBio = shortBio;}
public String getFullBio() {return fullBio;}
public void setFullBio(String fullBio) {this.fullBio = fullBio;}
}
也许不是最好的解决办法,但现在我有了不同的问题。。有没有办法对
Firestore
进行子字符串搜索?如db.collection(“klasiki”)。whereEqualTo(“name”,Ja)
并显示以Ja
开头的名称。要搜索写入程序,您需要创建查询
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query nameOfTheWritterQuery = rootRef.collection("writters")
.whereEqualTo("writterName", "Eidemanis Roberts");
看到您的Klasiki
类,我需要告诉您,您不遵守所有字段的规则,并且在反序列化时可能会遇到问题。您的模型类应如下所示:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
// Retrieve the SearchView and plug it into SearchManager
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String text) {
querySearch = db.collection("klasiki").whereEqualTo("name", text);
if (!text.trim().isEmpty()){
getList(querySearch);
adapter.startListening();
}
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText.trim().isEmpty()){
getList(queryFinal);
adapter.startListening();
}
return false;
}
});
return true;
}
public class Klasiki {
private String name, image, shortBio, fullBio;
public Klasiki( ){}
public Klasiki(String name, String image, String shortBio, String fullBio) {
this.name = name;
this.image = image;
this.shortBio = shortBio;
this.fullBio = fullBio;
}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getImage() {return image;}
public void setImage(String image) {this.image = image;}
public String getShortBio() {return shortBio;}
public void setShortBio(String shortBio) {this.shortBio = shortBio;}
public String getFullBio() {return fullBio;}
public void setFullBio(String fullBio) {this.fullBio = fullBio;}
}
请现在查看字段。所有开始都是小写字母。使用此代码时会发生什么?我创建了一个特定的布局/设计,每次有新的编写器时,我都会将其放入回收视图中,其中包含firestore中的值。是应用程序外观的链接。基本上,我想在顶部添加搜索功能,这样我可以在键入搜索时过滤编剧。你想实现什么样的搜索?只搜索编剧姓名。不需要把任何事情复杂化。。如果需要的话,我可以给你我的DB结构,但我认为没有必要。你如何在这个类中调用适配器,你能给我看一下完整的代码吗,我有一个问题,因为你似乎做不到。谢谢你指出这一点。通常情况下,我试着理解你必须从一封小信开始,但这封信写得很匆忙。同样关于您的查询,现在我开始了解如何创建查询以从数据库中获取特定信息。但问题是,如何修改我的
支架
和适配器
,使其只显示输入的名称是搜索栏。我想我必须将所有内容都保存为某种列表,并以这种方式排序,甚至不要使用FirestoreRecyclerAdapter
,因为我查找的几乎所有指南都使用预先制作的列表来过滤内容。有关搜索的所有内容都可以通过查询解决。大学教师;不要忘记,您还可以在单个字段上执行范围比较(=)。如果你想要更高级的搜索,你可以使用:Elasticsearch
或者。那么,如果我使用query进行搜索,我该如何准确地实现这个代码的搜索功能呢?在我有一个想法,它可能是通过查询完成的,但如何确切地做到这一点,我不知道。不过无论如何,谢谢你的回答。现在至少我知道要查找什么了。您需要将WriterQuery的名称
传递给FirestoreRecyclerOptions
对象,然后在FirestoreRecyclerAdapter
中使用此对象。就是这样。我更新了帖子(这里没有足够的空间发布代码和问题)。