【问题标题】:How to search among multiple words by using a SearchView?如何使用 SearchView 在多个单词中进行搜索?
【发布时间】:2019-07-19 23:55:14
【问题描述】:

我正在尝试使用 SearchView 搜索 SQLite 数据库。目前,我只能按一个字搜索。

例如“你好,我叫 Bob,我有一只猫”
如果我要从上面的文本中搜索一个单词(“Bob”),则会显示整行。
但是,我希望在搜索“bob cat”或“my name have”时也显示上述文本。因为这会返回一个空白列表视图。

此数据显示在列表视图中。

private void searchUsers(SearchView searchDB) {

    Cursor cursor = myDb.searchUsers(searchDB);

    if (cursor.getCount() == 0) {
        Toast.makeText(activity_symptcheck.this, "No data to show", Toast.LENGTH_SHORT).show();
    } else {
        while (cursor.moveToNext()) {
            listItem.add("Illness: " + "\n" + cursor.getString(1) + "\n" + "Symptoms: " + "\n" + cursor.getString(2) + "\n" + "Treatments: " + "\n" + cursor.getString(3));
        }
        cursor.close();
        myDb.close();
    }

    searchDB.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String searchTxt) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String searchTxt) {
            ArrayList<String> userslist = new ArrayList<>();

            for (String user : listItem) {
                if (user.toLowerCase().contains(searchTxt.toLowerCase())) {
                        userslist.add(user);
                    }
                }

            ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity_symptcheck.this,
                    android.R.layout.simple_list_item_1, userslist);
            ListIllness.setAdapter(adapter);

            return true;
        }
    });
}

public Cursor searchUsers(SearchView searchDB) {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+COL_3+" LIKE '%"+searchDB.getQuery()+"%'"+searchDB.getQuery(), null);

    return cursor;
}

【问题讨论】:

    标签: java android sqlite listview searchview


    【解决方案1】:

    如果您通过空格将输入与编辑文本分开并将其与您的字符串匹配,您可能会得到更好的结果

    String[] searchTextArray = searchText.split();
    for (String user : listItem){
        for (String part : searchTextArray){
            if (user.toLowerCase().contains(part.toLowerCase()){
                userlist.add(user);
                break;
            }
         }
    }
    

    请注意,这是未经测试的代码。

    如果你收集了所有匹配项,我猜你可以用 spannablestrings 标记名称中的匹配项。

    【讨论】:

      【解决方案2】:

      如果getQuery() 返回要搜索的String(如“Bob cat”),那么您可以像这样构造查询:

      String toSearch = getQuery();
      String pattern = "%" + toSearch.replace(" ", "%") + "%";
      String query = "SELECT * FROM " + TABLE_NAME + " WHERE " + COL_3 + " LIKE " + pattern;
      

      【讨论】:

      • 'Hello my name is Bob, I have a Cat' LIKE '%bob%cat%'TRUE'Hello my name is Bob, I have a Cat' LIKE '%my%name%have%' 也是 TRUE。所以要么你做错了什么,要么你没有正确解释你需要什么。
      【解决方案3】:

      您需要将字符串拆分为单独的单词,然后动态构建 WHERE 查询以匹配每个单词。

      您可以通过按空格对搜索字符串应用拆分来获取所有单词的列表。

      String[] words = "search string".split("\\s")
      
      String query = "SELECT * FROM "+TABLE_NAME+" WHERE "+COL_3+" LIKE '%"+words[0]+"%'"
      
      for(int i=1;i<words.length;i++){
          query += " AND '%"+words[i]+"%'"
      }
      

      更新为 \\s

      【讨论】:

      • 您需要将" " 替换为\\s
      • 这应该可以,如果有其他错误,请检查您的逻辑。让我知道您面临的问题,以便我提供帮助
      【解决方案4】:

      我是这样做的:

      • 为过滤器输入创建一个类。当用户单击搜索按钮时,将所有过滤器值分配给该类。

      • 在模型类中创建一个方法,如果任何过滤器值匹配,则返回 true。这需要过滤器类对象作为参数。

      • 现在当用户点击搜索按钮时,遍历数组中的每个对象。调用此方法。如果返回 true,则将此对象添加到新的过滤器数组中。

      示例

      ---- Filter class -----
      class FilterTrucks {
      
      String location;
      int capacityStart;
      int capacityEnd;
      Arraylist<String> availability;
      
      }
      
      ---- You model class -----
      class Mytrucks {
      
      String name;
      String location;
      int capacity;
      String availability;
      
      boolean matchFilter(FilterTrucks filter) {
      
      boolean locationMatch = filterMatchesLocation(filter);
      if(locationMatch)
      return true;
      
      boolean matchCapacity = filterMatchesCapacity(filter);
      if(matchCapacity)
      return true;
      
      return false;
      
      }
      
      boolean filterMatchesLocation(FilterTrucks filter)  {
      return location.contains(filter.location);
      }
      
      boolean filterMatchesCapacity(FilterTrucks filter)  {
      return  (capacity >= filter.capacityStart ||  capacity <= filter.capacityEnd)
      }
      
      ----- Your activity -----
      
      Arraylist<Mytrucks> filterArray = new Arraylist<>();
      
      filter_search.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
      
      //create filter object from user selected fields
      FilterTrucks filter = new FilterTrucks();
      filter.location = txtLocation.getText().toString(); 
      
      for(Mytrucks truck : arraylist) {
      if(truck.matchFilter(filter)) 
          filterArray.add(truck);
      }
          }
      });
      
      //use filter array to populate recycler view
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多