我有一个使用Realm数据库获取数据的RecyclerView,我想在操作栏上实现SearchView,可以搜索RecyclerView的项目,这是我的代码,但我似乎无法使其工作
这是菜单XML
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:icon="@drawable/ic_search_white_24dp"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"/>
<item android:id="@+id/action_add"
android:icon="@drawable/ic_add_white_48dp"
android:title="Add"
app:showAsAction="ifRoom"/>
活动
中的onOptionsItemSelectedpublic boolean onOptionsItemSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
case R.id.action_search:
// search action
SearchView searchView=(SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
//adapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//adapter.getFilter().filter(newText);
newText=newText.toLowerCase();
System.out.println(results);
ArrayList<UserInfo> newList=new ArrayList<>();
for (UserInfo userInfo : results){
String username=userInfo.getUsername().toLowerCase();
String password=userInfo.getPassword().toLowerCase();
String type=userInfo.getType().toLowerCase();
if (username.contains(newText)||password.contains(newText)||type.contains(newText)){
newList.add(userInfo);
}
}
adapter.setFilter(newList);
return true;
}
});
return true;
case R.id.action_add:
addInfo();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
我的适配器类
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
private LayoutInflater layoutInflater;
java.util.List<UserInfo> data= Collections.emptyList();
ArrayList<UserInfo> arrayList;
public Adapter(Context context, java.util.List<UserInfo> data){
layoutInflater=LayoutInflater.from(context);
this.data=data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=layoutInflater.inflate(R.layout.list_item , parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
UserInfo current=data.get(position);
holder.username.setText("Username: "+current.username);
holder.password.setText("Password: "+current.password);
holder.type.setText("Type: "+current.type);
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView username,password,type;
public MyViewHolder(View itemView) {
super(itemView);
username= (TextView) itemView.findViewById(R.id.username_TV);
password= (TextView) itemView.findViewById(R.id.password_TV);
type= (TextView) itemView.findViewById(R.id.type_TV);
}
}
public void setFilter(List<UserInfo> newList){
arrayList=new ArrayList<>();
arrayList.addAll(newList);
notifyDataSetChanged();
}
}
答案 0 :(得分:2)
这是我的问题的解决方案 首先在onCreateOptionsMenu上添加此
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_actions, menu);
MenuItem search=menu.findItem(R.id.action_search);
//this 2 lines
SearchView searchView=(SearchView)search.getActionView();
search(searchView);
return super.onCreateOptionsMenu(menu);
}
搜索方法
private void search(SearchView searchView) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
newText=newText.toLowerCase();
ArrayList<UserInfo> newList=new ArrayList<>();
for (UserInfo userInfo : results){
String username=userInfo.getUsername().toLowerCase();
String password=userInfo.getPassword().toLowerCase();
String type=userInfo.getType().toLowerCase();
if (username.contains(newText)||password.contains(newText)||type.contains(newText)){
newList.add(userInfo);
}
}
adapter.setFilter(newList);
return true;
}
});
}
在适配器
处写入的setFilter方法public void setFilter(List<UserInfo> newList){
data=new ArrayList<>();
data.addAll(newList);
notifyDataSetChanged();
}
答案 1 :(得分:0)
您似乎在 setFilter 方法中使用 arrayList 而非数据,请使用数据代替< / p>
答案 2 :(得分:0)
我希望这个答案对你有帮助Mahmoud Omara
你好Mahmoud Omara你在使用领域数据库。
在Recyclerview适配器中实现Filterable,然后生成@Override方法getFilter。
然后实现你自己的过滤器看起来我已经改变你的适配器
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> implements Filterable {
private LayoutInflater layoutInflater;
java.util.List<UserInfo> data= Collections.emptyList();
public Adapter(Context context, java.util.List<UserInfo> data){
layoutInflater=LayoutInflater.from(context);
this.data=data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=layoutInflater.inflate(R.layout.list_item , parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
UserInfo current=data.get(position);
holder.username.setText("Username: "+current.username);
holder.password.setText("Password: "+current.password);
holder.type.setText("Type: "+current.type);
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView username,password,type;
public MyViewHolder(View itemView) {
super(itemView);
username= (TextView) itemView.findViewById(R.id.username_TV);
password= (TextView) itemView.findViewById(R.id.password_TV);
type= (TextView) itemView.findViewById(R.id.type_TV);
}
}
@Override
public Filter getFilter() {
return new MyNamesFilter();
}
private class MyNamesFilter
extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//myRealm is your realm object
//contactName is in your database column name replace your table name column
RealmResults<Contact> contactArrayLisst = myRealm.where(Contact.class)
.beginGroup()
.contains("contactName", constraint.toString(), Case.INSENSITIVE)
.endGroup()
.findAll();
data.clear();
data.addAll(contactArrayLisst);
notifyDataSetChanged();
}
}
}
然后在queryTextChange方法
上更改您的活动类看起来像这样
adapter.getFilter().filter(s);
答案 3 :(得分:0)
可在您的适配器类上过滤的实现。 覆盖getFilter方法。
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if(charSequence == null | charSequence.length() == 0){
filterResults.count = getUserModelListFiltered.size();
filterResults.values = getUserModelListFiltered;
}else{
String searchChr = charSequence.toString().toLowerCase();
List<UserModel> resultData = new ArrayList<>();
for(UserModel userModel: getUserModelListFiltered){
if(userModel.getUserName().toLowerCase().contains(searchChr)){
resultData.add(userModel);
}
}
filterResults.count = resultData.size();
filterResults.values = resultData;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
userModelList = (List<UserModel>) filterResults.values;
notifyDataSetChanged();
}
};
return filter;
}
在您的主要活动中,创建您的搜索视图并对querytextchange执行过滤。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem menuItem = menu.findItem(R.id.search_view);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
usersAdapter.getFilter().filter(newText);
return true;
}
});
return true;
}
您可以在此处找到完整的教程和源代码。 Recyclerview with searchview
答案 4 :(得分:0)
希望这个答案对您有帮助。
首先,您需要创建两个ArrayList
,即oriList
保留原始列表,modList
保留过滤的数据。
private ArrayList<SingleData> modList;
private ArrayList<SingleData> original;
1。。在constructer
中将它们都初始化了,或者在适配器中创建一个方法来设置您的值,如下所示
public void setEmployees(ArrayList<SingleData> dataList) {
this.dataList = new ArrayList<>();
this.dataList = dataList;
oriDataList = new ArrayList<>();
oriDataList = (ArrayList<SingleData>) dataList.clone();
notifyDataSetChanged();
}
**注意:** 1。如果您不想更改原始列表数据,请使用 添加新列表时使用
clone()
方法。
2。。创建了另一个方法来处理搜索查询:
public void filter(String text) {
dataList.clear();
if (text.isEmpty()) {
dataList.addAll(oriDataList);
} else {
text = text.toLowerCase();
for (SingleData item : oriDataList) {
if (item.getName().toLowerCase().contains(text)) {
dataList.add(item);
}
}
}
notifyDataSetChanged();
}
3。从下面的活动或片段中调用搜索方法
YOUR_ADAPTER_OBJECT.filter(PASS_SEARCH_TEXT_HERE);
4。。SingleData
是pojo类
public class SingleData{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
答案 5 :(得分:0)
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return true;
}
@Override
public boolean onQueryTextChange(String s) {
searchKeyword = s;
s=s.toLowerCase();
ArrayList<GetGoogleTemplesResponse.ResultsBean> temples=new ArrayList<>();
for (GetGoogleTemplesResponse.ResultsBean bean : results){
String templeName=bean.getName().toLowerCase();
if (templeName.contains(s)){
temples.add(bean);
}
}
adapter.setFilter(temples);
return true;
}
});
在适配器中
public void setFilter(List<GetGoogleTemplesResponse.ResultsBean> list){
beans=new ArrayList<>();
beans.addAll(list);
notifyDataSetChanged();
}