You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于SQLite的Android RecyclerView中实现SearchView搜索功能

实现步骤

1. 修改MyDatabaseHelper类,添加搜索查询方法

在MyDatabaseHelper.java中新增模糊搜索方法,支持按患者姓名、疾病匹配:

// 添加到MyDatabaseHelper类中
public Cursor searchPatients(String keyword) {
    SQLiteDatabase db = this.getReadableDatabase();
    String query = "SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_NAME + " LIKE ? OR " + COLUMN_DISEASE + " LIKE ?";
    String[] selectionArgs = new String[]{"%" + keyword + "%", "%" + keyword + "%"};
    return db.rawQuery(query, selectionArgs);
}

2. 修改CustomAdapter类,实现筛选逻辑

让Adapter实现Filterable接口,区分全量原始数据和筛选后数据,实现搜索过滤逻辑:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> implements Filterable {

    private Context context;
    // 全量原始数据
    private ArrayList<String> originalId, originalName, originalDisease, originalMedicine, originalMobile, originalAddress, originalDay, originalMonth, originalYear;
    // 筛选后展示数据
    private ArrayList<String> filteredId, filteredName, filteredDisease, filteredMedicine, filteredMobile, filteredAddress, filteredDay, filteredMonth, filteredYear;

    CustomAdapter(Context context, ArrayList<String> _id, ArrayList<String> name, ArrayList<String> disease,
                  ArrayList<String> medicine, ArrayList<String> mobile, ArrayList<String> address, ArrayList<String> day, ArrayList<String> month, ArrayList<String> year){
        this.context = context;
        this.originalId = _id;
        this.originalName = name;
        this.originalDisease = disease;
        this.originalMedicine = medicine;
        this.originalMobile = mobile;
        this.originalAddress = address;
        this.originalDay = day;
        this.originalMonth = month;
        this.originalYear = year;
        // 初始状态下筛选数据等于全量数据
        this.filteredId = _id;
        this.filteredName = name;
        this.filteredDisease = disease;
        this.filteredMedicine = medicine;
        this.filteredMobile = mobile;
        this.filteredAddress = address;
        this.filteredDay = day;
        this.filteredMonth = month;
        this.filteredYear = year;
    }

    @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);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        // 绑定筛选后的数据
        holder.id_txt.setText(String.valueOf(filteredId.get(position)));
        holder.name_txt.setText(String.valueOf(filteredName.get(position)));
        holder.disease_txt.setText(String.valueOf(filteredDisease.get(position)));
        holder.medicine_txt.setText(String.valueOf(filteredMedicine.get(position)));
        holder.mobile_txt.setText(String.valueOf(filteredMobile.get(position)));
        holder.address_txt.setText(String.valueOf(filteredAddress.get(position)));
        holder.day_txt.setText(String.valueOf(filteredDay.get(position)));
        holder.month_txt.setText(String.valueOf(filteredMonth.get(position)));
        holder.year_txt.setText(String.valueOf(filteredYear.get(position)));
    }

    @Override
    public int getItemCount() {
        return filteredId.size();
    }

    // 实现过滤逻辑
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String searchKey = constraint.toString().toLowerCase().trim();
                if(searchKey.isEmpty()){
                    // 搜索为空时返回全量数据
                    filteredId = originalId;
                    filteredName = originalName;
                    filteredDisease = originalDisease;
                    filteredMedicine = originalMedicine;
                    filteredMobile = originalMobile;
                    filteredAddress = originalAddress;
                    filteredDay = originalDay;
                    filteredMonth = originalMonth;
                    filteredYear = originalYear;
                }else{
                    ArrayList<String> tempId = new ArrayList<>();
                    ArrayList<String> tempName = new ArrayList<>();
                    ArrayList<String> tempDisease = new ArrayList<>();
                    ArrayList<String> tempMedicine = new ArrayList<>();
                    ArrayList<String> tempMobile = new ArrayList<>();
                    ArrayList<String> tempAddress = new ArrayList<>();
                    ArrayList<String> tempDay = new ArrayList<>();
                    ArrayList<String> tempMonth = new ArrayList<>();
                    ArrayList<String> tempYear = new ArrayList<>();
                    for(int i=0; i<originalId.size(); i++){
                        // 匹配姓名或疾病,不区分大小写
                        if(originalName.get(i).toLowerCase().contains(searchKey) || originalDisease.get(i).toLowerCase().contains(searchKey)){
                            tempId.add(originalId.get(i));
                            tempName.add(originalName.get(i));
                            tempDisease.add(originalDisease.get(i));
                            tempMedicine.add(originalMedicine.get(i));
                            tempMobile.add(originalMobile.get(i));
                            tempAddress.add(originalAddress.get(i));
                            tempDay.add(originalDay.get(i));
                            tempMonth.add(originalMonth.get(i));
                            tempYear.add(originalYear.get(i));
                        }
                    }
                    filteredId = tempId;
                    filteredName = tempName;
                    filteredDisease = tempDisease;
                    filteredMedicine = tempMedicine;
                    filteredMobile = tempMobile;
                    filteredAddress = tempAddress;
                    filteredDay = tempDay;
                    filteredMonth = tempMonth;
                    filteredYear = tempYear;
                }
                FilterResults results = new FilterResults();
                results.values = filteredId;
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                notifyDataSetChanged();
            }
        };
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView id_txt, name_txt, disease_txt, medicine_txt, mobile_txt, address_txt, day_txt, month_txt, year_txt;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            id_txt = itemView.findViewById(R.id.id_txt);
            name_txt = itemView.findViewById(R.id.name_txt);
            disease_txt = itemView.findViewById(R.id.disease_txt);
            medicine_txt = itemView.findViewById(R.id.medicine_txt);
            mobile_txt = itemView.findViewById(R.id.mobile_txt);
            address_txt = itemView.findViewById(R.id.address_txt);
            day_txt = itemView.findViewById(R.id.day_txt);
            month_txt = itemView.findViewById(R.id.month_txt);
            year_txt = itemView.findViewById(R.id.year_txt);
        }
    }
}

3. 新增SearchView到activity_main布局

在主页面布局中添加搜索控件,放在RecyclerView上方:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:queryHint="搜索患者姓名/疾病"
        android:iconifiedByDefault="false"
        android:padding="8dp"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/add_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@android:drawable/ic_menu_add"/>
</LinearLayout>

4. 修改MainActivity类,关联搜索逻辑

在MainActivity中绑定SearchView监听,同时新增onResume方法刷新数据,保证新增患者后数据同步:

public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    FloatingActionButton add_button;
    SearchView searchView; // 新增搜索控件变量
    MyDatabaseHelper myDB;
    ArrayList<String> _id, name, disease, medicine, mobile, address, day, month, year;
    CustomAdapter customAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recyclerView);
        add_button = findViewById(R.id.add_button);
        searchView = findViewById(R.id.searchView); // 绑定搜索控件
        add_button.setOnClickListener(v -> {
            Intent intent = new Intent(MainActivity.this, AddActivity.class);
            startActivity(intent);
        });
        myDB = new MyDatabaseHelper(MainActivity.this);
        _id = new ArrayList<>();
        name = new ArrayList<>();
        disease = new ArrayList<>();
        medicine = new ArrayList<>();
        mobile = new ArrayList<>();
        address = new ArrayList<>();
        day = new ArrayList<>();
        month = new ArrayList<>();
        year = new ArrayList<>();
        storeDataInArrays();
        customAdapter = new CustomAdapter(MainActivity.this, _id, name, disease, medicine, mobile, address, day, month, year);
        recyclerView.setAdapter(customAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        // 设置搜索监听
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                customAdapter.getFilter().filter(query);
                return false;
            }
            @Override
            public boolean onQueryTextChange(String newText) {
                customAdapter.getFilter().filter(newText);
                return false;
            }
        });
    }
    
    // 新增页面回到前台时刷新数据
    @Override
    protected void onResume() {
        super.onResume();
        _id.clear();
        name.clear();
        disease.clear();
        medicine.clear();
        mobile.clear();
        address.clear();
        day.clear();
        month.clear();
        year.clear();
        storeDataInArrays();
        customAdapter = new CustomAdapter(MainActivity.this, _id, name, disease, medicine, mobile, address, day, month, year);
        recyclerView.setAdapter(customAdapter);
        // 保留当前搜索状态
        if(!searchView.getQuery().toString().isEmpty()){
            customAdapter.getFilter().filter(searchView.getQuery().toString());
        }
    }

    void storeDataInArrays(){
        Cursor cursor = myDB.readAllData();
        if(cursor.getCount() == 0){
            Toast.makeText(this, "No data.", Toast.LENGTH_SHORT).show();
        }else{
            while (cursor.moveToNext()){
                _id.add(cursor.getString(0));
                name.add(cursor.getString(1));
                disease.add(cursor.getString(2));
                medicine.add(cursor.getString(3));
                mobile.add(String.valueOf(cursor.getLong(4)));
                address.add(cursor.getString(5));
                day.add(cursor.getString(6));
                month.add(cursor.getString(7));
                year.add(cursor.getString(8));
            }
        }
    }
}

如需扩展搜索范围(比如支持手机号、地址搜索),只需修改CustomAdapter的过滤逻辑,新增对应字段的匹配判断即可。

内容的提问来源于stack exchange,提问作者Tejas Dalvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 23:57:03