Android 如何使用RecyclerView实现搜索过滤器
我在youtube上学习了一些关于SQLite和RecyclerView()的教程,我完成了所有的工作,并根据需要对其进行了自定义,以使我的应用程序和所有工作正常 现在我要做的就是在顶部(操作栏)添加搜索按钮,我可以从我的RecyclerView中搜索项目。 所以我试图找出如何实现它,但我很难解决过滤器和所有这些问题。我看到的关于列表(E)的所有教程都可以使用,而我的CustomeAdpter geting ArrayList无法理解如何使用ArrayList 因此,如果有人能帮助我,给我一些小指导,我将不胜感激 编辑 我在适配器中添加了Android 如何使用RecyclerView实现搜索过滤器,android,android-recyclerview,android-sqlite,android-search,Android,Android Recyclerview,Android Sqlite,Android Search,我在youtube上学习了一些关于SQLite和RecyclerView()的教程,我完成了所有的工作,并根据需要对其进行了自定义,以使我的应用程序和所有工作正常 现在我要做的就是在顶部(操作栏)添加搜索按钮,我可以从我的RecyclerView中搜索项目。 所以我试图找出如何实现它,但我很难解决过滤器和所有这些问题。我看到的关于列表(E)的所有教程都可以使用,而我的CustomeAdpter geting ArrayList无法理解如何使用ArrayList 因此,如果有人能帮助我,给我一些小
getFilter()
函数,但是当我试图搜索某个东西时,在RecyclerView中什么也没有发生。
我正在添加代码:MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity = MainActivity.this;
noClubsImage = findViewById(R.id.noClubsImage);
noClubsText = findViewById(R.id.noClubsText);
recyclerView = findViewById(R.id.recyclerView);
add_button = findViewById(R.id.add_button);
add_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
activity.startActivityForResult(intent,1);
}
});
myDB = new MyDatabaseHelper(MainActivity.this);
club_id = new ArrayList<>();
club_name = new ArrayList<>();
join_date = new ArrayList<>();
expire_date = new ArrayList<>();
storeDataInArrays();
customAdapter = new CustomAdapter(MainActivity.this, this, club_id, club_name, join_date, expire_date);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
这是我的适配器:
我在onBindViewHolder中添加了Try&catch函数,因为如果没有,它将崩溃,并出现以下错误:“java.lang.IndexOutOfBoundsException:索引:1,大小:1”
添加后,我可以搜索一些非常奇怪的东西,上传一些图片:
公共类CustomAdapter扩展了RecyclerView。适配器实现了可过滤{
私人语境;
私人活动;
私人阵列列表俱乐部id、俱乐部名称、加入日期、到期日期、列表、原始列表;
内部位置;
动画翻译;
CustomAdapter(活动活动、上下文上下文、ArrayList club\u id、ArrayList club\u名称、ArrayList加入日期、ArrayList过期日期){
这个。活动=活动;
this.context=上下文;
this.club\u id=club\u id;
this.club\u name=club\u name;
this.join\u date=加入日期;
this.expire\u date=expire\u date;
this.list=俱乐部名称;
this.originalList=俱乐部名称;
}
@非空
@凌驾
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){
LayoutFlater充气机=LayoutFlater.from(上下文);
视图=充气机。充气(R.layout.my_row,parent,false);
返回新的MyViewHolder(视图);
}
公共过滤器getFilter(){
返回新筛选器(){
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
ArrayList filteredResults=null;
if(constraint.length()==0){
filteredResults=俱乐部名称;
}否则{
filteredResults=getFilteredResults(constraint.toString().toLowerCase());
}
FilterResults results=新的FilterResults();
results.values=filteredResults;
Log.d(“Test”,filteredResults.toString());
返回结果;
}
@凌驾
受保护的void publishResults(CharSequence约束、FilterResults结果){
俱乐部名称=(ArrayList)results.values;
notifyDataSetChanged();
}
};
}
受保护的ArrayList getFilteredResults(字符串约束){
ArrayList结果=新建ArrayList();
用于(对象项:原始列表){
if(item.toString().toLowerCase()包含(约束)){
添加(item.toString());
}
}
//Log.d(“Test”,results.toString());
返回结果;
}
@凌驾
public void onBindViewHolder(@NonNull MyViewHolder holder,final int位置){
试一试{
这个位置=位置;
holder.club_name_txt.setText(String.valueOf(club_name.get(position));
holder.join_txt.setText(String.valueOf(join_date.get(position));
holder.expire_txt.setText(String.valueOf(expire_date.get(position));
holder.mainLayout.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
意向意向=新意向(上下文,UpdateActivity.class);
intent.putExtra(“club_id”,String.valueOf(club_id.get(position));
intent.putExtra(“club_name”,String.valueOf(club_name.get(position));
intent.putExtra(“join_date”,String.valueOf(join_date.get(position));
intent.putExtra(“expire_date”,String.valueOf(expire_date.get(position));
活动。startActivityForResult(意图,1);
}
});
}捕获(例外情况除外){
Log.e(“标记”,“执行数据库事务时捕获异常”);
例如printStackTrace();
}
}
@凌驾
public int getItemCount(){
返回俱乐部id.大小();
}
公共类MyViewHolder扩展了RecyclerView.ViewHolder{
线性布局主布局;
text查看俱乐部id、俱乐部名称、加入、过期;
公共MyViewHolder(@NonNull View itemView){
超级(项目视图);
club\u name\u txt=itemviewbyd(R.id.club\u name\u txt);
join_txt=itemView.findviewbyd(R.id.jDate_txt);
expire_txt=itemviewbyd(R.id.eDate_txt);
mainLayout=itemView.findViewById(R.id.mainLayout);
translate\u anim=AnimationUtils.loadAnimation(上下文,R.anim.translate\u anim);
设置动画(翻译动画);
}
}}
您拥有customAdapter.getFilter()在OnQueryTextListener
的两种方法中都使用code>line,它会为您返回过滤器。这就是您所要求的,您从未将字符串
传递给此筛选器。这条线应该是这样的
customAdapter.getFilter().filter(query); // or newText, depend on OnQueryTextListener method
根据评论进行编辑:
删除此尝试{}catch()
并修复异常。这种方法是可靠的,只有你的错误才能导致崩溃
您只筛选和发布了一个数组(club_name=(ArrayList)results.values;
),但仍然通知adapter
,列表中的项目数等于club_id.size()代码>在getItemCount
中。这就是为什么您将获得索引自动边界异常-俱乐部id
未被触及,并且有多个项目,即使在俱乐部
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> implements Filterable{
private Context context;
private Activity activity;
private ArrayList club_id, club_name, join_date,expire_date,list,originalList;
int position;
Animation translate_anim;
CustomAdapter(Activity activity, Context context, ArrayList club_id, ArrayList club_name, ArrayList join_date, ArrayList expire_date){
this.activity = activity;
this.context = context;
this.club_id = club_id;
this.club_name = club_name;
this.join_date = join_date;
this.expire_date = expire_date;
this.list = club_name;
this.originalList = club_name;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.my_row,parent,false);
return new MyViewHolder(view);
}
public Filter getFilter(){
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList filteredResults = null;
if (constraint.length() == 0) {
filteredResults = club_name;
} else {
filteredResults = getFilteredResults(constraint.toString().toLowerCase());
}
FilterResults results = new FilterResults();
results.values = filteredResults;
Log.d("Test",filteredResults.toString());
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
club_name = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
};
}
protected ArrayList getFilteredResults(String constraint) {
ArrayList results = new ArrayList<>();
for (Object item : originalList) {
if (item.toString().toLowerCase().contains(constraint)) {
results.add(item.toString());
}
}
//Log.d("Test",results.toString());
return results;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
try{
this.position = position;
holder.club_name_txt.setText(String.valueOf(club_name.get(position)));
holder.join_txt.setText(String.valueOf(join_date.get(position)));
holder.expire_txt.setText(String.valueOf(expire_date.get(position)));
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context,UpdateActivity.class);
intent.putExtra("club_id",String.valueOf(club_id.get(position)));
intent.putExtra("club_name",String.valueOf(club_name.get(position)));
intent.putExtra("join_date",String.valueOf(join_date.get(position)));
intent.putExtra("expire_date",String.valueOf(expire_date.get(position)));
activity.startActivityForResult(intent,1);
}
});
}catch(Exception ex) {
Log.e("TAG", "EXCEPTION CAUGHT WHILE EXECUTING DATABASE TRANSACTION");
ex.printStackTrace();
}
}
@Override
public int getItemCount() {
return club_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
LinearLayout mainLayout;
TextView club_id_txt, club_name_txt, join_txt,expire_txt;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
club_name_txt = itemView.findViewById(R.id.club_name_txt);
join_txt = itemView.findViewById(R.id.jDate_txt);
expire_txt = itemView.findViewById(R.id.eDate_txt);
mainLayout = itemView.findViewById(R.id.mainLayout);
translate_anim = AnimationUtils.loadAnimation(context, R.anim.translate_anim);
mainLayout.setAnimation(translate_anim);
}
}}
customAdapter.getFilter().filter(query); // or newText, depend on OnQueryTextListener method
CustomAdapter(Activity activity, Context context, ArrayList club_id, ArrayList club_name, ArrayList join_date, ArrayList expire_date){
this.activity = activity;
this.context = context;
this.club_id_org = club_id;
this.club_name_org = club_name;
this.join_date_org = join_date;
this.expire_date_org = expire_date;
this.club_id = new ArrayList<>();
this.club_id.addAll(this.club_id_org);
this.club_name = new ArrayList<>();
this.club_name.addAll(this.club_name_org);
this.join_date = new ArrayList<>();
this.join_date.addAll(this.join_date_org);
this.expire_date = new ArrayList<>();
this.expire_date.addAll(this.expire_date_org);
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList club_id_temp = new Arraylist<>(),
club_name_temp = new Arraylist<>(),
join_date_temp = new Arraylist<>(),
expire_date_temp = new Arraylist<>();
if (constraint.length() == 0) {
club_id_temp.addAll(club_id_org);
club_name_temp.addAll(club_name_org);
join_date_temp.addAll(join_date_org);
expire_date_temp.addAll(expire_date_org);
} else {
for(int i=0; i<club_name_org.size(); i++){
if(club_name_org.get(i).toLowerCase().contains(constraint.toLowerCase())){
club_id_temp.add(club_id_org.get(i));
club_name_temp.add(club_name_org.get(i));
join_date_temp.add(join_date_org.get(i));
expire_date_temp.add(expire_date_org.get(i));
}
}
}
FilterResults results = new FilterResults();
results.values = ...
public static class TempArrays{
public ArrayList club_id, club_name, join_date, expire_date;
}
FilterResults results = new FilterResults();
TempArrays ta = new TempArrays();
ta.club_id = club_id_temp;
ta.club_name = club_name_temp;
ta.join_date = join_date_temp;
ta.expire_date = expire_date_temp;
results.values = ta;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
TempArrays ta = (TempArrays) results.values;
club_id = ta.club_id;
club_name = ta.club_name;
join_date = ta.join_date;
expire_date = ta.expire_date;
notifyDataSetChanged();
}
public static class ClubModel{
public String club_id, club_name, join_date, expire_date;
}