我正在使用自定义ArrayAdapter 存储用户信息,例如sammy,robert,lizie都是一个User对象,并且我正在使用用户类型 ArrayList 存储所有用户对象 ArrayList 。
并且因为它不是字符串或int(ArrayList),所以默认的 getFilter 不起作用,我已经完成了研究,但确实使 getFilter 感到困惑>方法有效,所以我可以修改自己。
我要基于name
User class
属性来实现搜索
我知道我必须在 CustomAdapter 类中实现 Filterable 接口,但是 getFilter 确实不直观。
这是我的CustomAdapter
class CustomArrayAdapter extends ArrayAdapter<User> implements Filterable {
CustomArrayAdapter(@NonNull Context context, ArrayList<User> users) {
super(context, 0, users);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
User innserUser = getItem(position);
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);
}
TextView username = (TextView) convertView.findViewById(R.id.userNameContact);
TextView userNumber = (TextView) convertView.findViewById(R.id.userNumberContact);
ImageView userImage = (ImageView) convertView.findViewById(R.id.userImageContact);
try {
if(innserUser != null) {
username.setText(innserUser.name);
userNumber.setText(innserUser.number);
userImage.setImageBitmap(innserUser.imageBitmap);
}
}catch (Exception e){
e.printStackTrace();
}
return convertView;
}
}
这是这里的用户类别,没什么特别的
import android.graphics.Bitmap;
public class User {
String id, name, number;
Bitmap imageBitmap;
User(String id, String name, String number, Bitmap imageBitmap){
this.id = id;
this.name = name;
this.number = number;
this.imageBitmap = imageBitmap;
}
}
我从许多线程中捆绑了许多 getFilter 的变体,但它们都不适合我,而那些很好解释的是BaseAdapter而不是ArrayAdapter
我已经尝试过question,而我已经尝试过question,但对我不起作用。
我是android开发领域的新手,这似乎特别不直观。 任何建议将不胜感激,谢谢。
编辑1 :在回答 jitesh mohite 之后,感谢您重播 jitesh mohite
class CustomArrayAdapter extends ArrayAdapter<User> implements Filterable {
ArrayList<User> users;
CustomArrayAdapter(@NonNull Context context, ArrayList<User> users) {
super(context, 0, users);
this.users = users;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
User innserUser = getItem(position);
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);
}
TextView username = (TextView) convertView.findViewById(R.id.userNameContact);
TextView userNumber = (TextView) convertView.findViewById(R.id.userNumberContact);
ImageView userImage = (ImageView) convertView.findViewById(R.id.userImageContact);
try {
if(innserUser != null) {
username.setText(innserUser.name);
userNumber.setText(innserUser.number);
userImage.setImageBitmap(innserUser.imageBitmap);
}
}catch (Exception e){
e.printStackTrace();
}
return convertView;
}
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<User> tempList=new ArrayList<User>();
// Add the filter code here
if(constraint != null && users != null) {
int length= users.size();
int i=0;
while(i<length){
User item= users.get(i);
//do whatever you wanna do here
//adding result set output array
//item.name is user.name cause i want to search on name
if(item.name.toLowerCase().contains(constraint.toString().toLowerCase()) ) { // Add check here, and fill the tempList which shows as a result
tempList.add(item);
}
i++;
}
//following two lines is very important
//as publish result can only take FilterResults users
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence contraint, FilterResults results) {
users = (ArrayList<User>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
@Override
public Filter getFilter() {
return myFilter;
}
}
搜索仍然无法在自定义适配器上进行,我仍然认为自己做错了。
在这里我在搜索栏中输入了一些内容,但没有进行过滤
,如果您想查看搜索栏代码,它与通常的没什么不同
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_box, menu);
MenuItem item = menu.findItem(R.id.app_bar_search);
SearchView searchView = (SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
customArrayAdapter.getFilter().filter(newText);
return false;
}
});
return true;
}
答案 0 :(得分:1)
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<User> tempList=new ArrayList<User>();
// Add the filter code here
if(constraint != null && users!=null) {
int length= users.size();
int i=0;
while(i<length){
User item= users.get(i);
//do whatever you wanna do here
//adding result set output array
if() { // Add check here, and fill the tempList which shows as a result
tempList.add(item);
}
i++;
}
//following two lines is very important
//as publish result can only take FilterResults users
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence contraint, FilterResults results) {
users = (ArrayList<User>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
最后,重写此方法并返回过滤器实例。
@Override
public Filter getFilter() {
return myFilter;
}
答案 1 :(得分:1)
ArrayAdapter
的内置Filter
使用来自模型类的toString()
返回(即其类型参数)来执行其过滤比较。如果您能够覆盖Filter
的{{1}}方法以返回要比较的内容,则不一定需要自定义的User
实现,只要它的过滤算法适合您情况(请参见下文)。在这种情况下:
toString()
要确切了解该算法是什么,@Override
public String toString() {
return name;
}
的默认过滤如下:
过滤器ArrayAdapter
首先转换为小写。然后,遍历数据集,将每个值的String
返回值转换为小写字母,并检查其是否为toString()
过滤器startsWith()
。如果是这样,它将被添加到结果集中。如果不是,则执行第二次检查,从而将值的小写字母String
在空格(String
)上分割,然后再次使用" "
将其中的每个值与过滤器进行比较。基本上,它首先检查整个内容是否以过滤器文本开头,然后在必要时检查每个单词。
如果这是一个合适的过滤器,那么到目前为止,该解决方案是最简单的。