2014-11-06 98 views
9

我对使用SearchView非常陌生。我需要一个功能,我有一个ActionBar我已为其Search。当我点击搜索时,建议应显示在搜索字段下方的列表中。SearchView过滤和设置建议

我迄今所做的: 在menu.xml文件添加的搜索和onCreateOptionsMenu(),我初始化搜索查看和setSuggestionsAdapter还实现setOnQueryTextListener写的代码。

结果:我进入该应用,点击搜索图标,它会显示建议。我输入一个字母来排列匹配的字母。我输入第二个字母它显示没有建议。此外,我关闭searchview并再次打开它,键盘被打开,但列表中的建议不显示。

我需要的是:根据用户输入的字符进行过滤。即使它不止一个角色。 始终向所有列表项显示建议,或者在用户类型时显示建议。

我已经在Android的SearchView类中看到过,它们将文本设置为空,并且还将建议解除。但我不想要这个。

我被困在这里,不知道如何继续。请帮帮我。 这是我的适配器代码:

public class ExampleAdapter extends CursorAdapter implements Filterable { 

    private ArrayList<String> items; 
    private ArrayList<String> orig; 

    public ExampleAdapter(Context context, Cursor cursor, 
      ArrayList<String> items) { 
     super(context, cursor, false); 
     this.items = new ArrayList<String>(); 
     this.items = items; 
     orig = new ArrayList<String>(); 
     orig.addAll(items); 
    } 

    @Override 
    public int getCount() { 
     return items.size(); 
    } 

    @Override 
    public Filter getFilter() { 
     return new Filter() { 

      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       constraint = constraint.toString().toLowerCase(); 
       FilterResults result = new FilterResults(); 

       if (constraint != null 
         && constraint.toString().length() > 0) { 
        List<String> founded = new ArrayList<String>(); 
        for (int i = 0, l = orig.size(); i < l; i++) { 
         if (orig.get(i) 
           .toString() 
           .toLowerCase() 
           .startsWith(
             constraint.toString().toLowerCase())) 
          founded.add(orig.get(i)); 
        } 

        result.values = founded; 
        result.count = founded.size(); 
       } else { 
        synchronized (this) { 
         result.values = orig; 
         result.count = orig.size(); 
        } 

       } 
       return result; 

      } 

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

       items.clear(); 
       items = new ArrayList<String>(); 
       items = (ArrayList<String>) results.values; 
       notifyDataSetChanged(); 

      } 

     }; 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.textView.setText(items.get(cursor.getPosition())); 
    } 

    public class ViewHolder { 
     public TextView textView; 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     ViewHolder holder = new ViewHolder(); 
     View v = null; 

     LayoutInflater inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     v = inflater.inflate(R.layout.item, parent, false); 
     holder.textView = (TextView) v.findViewById(R.id.text); 

     v.setTag(holder); 
     return v; 

    } 
} 

代码在我的活动,我有搜索查看相关的菜单:

private String[] columns = new String[] { "_id", "text" }; 
    private SearchView searchView; 
    private SearchManager manager; 
    private ExampleAdapter aptr; 

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 

} 

@Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.main, menu); 
     MenuItem searchItem = menu.findItem(R.id.action_search); 
     searchView = (SearchView) MenuItemCompat.getActionView(searchItem); 
     setSearchTextColour(searchView); 
     setSearchIcons(searchView); 
     searchView.setQueryHint(Html.fromHtml("<font color = #ffffff>" 
       + getResources().getString(R.string.search_store) + "</font>")); 
     searchView.setSearchableInfo(manager 
       .getSearchableInfo(getComponentName())); 
     Object[] temp = new Object[] { 0, "default" }; 
     final MatrixCursor cursor = new MatrixCursor(columns); 
     for (int i = 0; i < alStoreNames.size(); i++) { 
      temp[0] = i; 
      temp[1] = alStoreNames.get(i); 
      cursor.addRow(temp); 
     } 
     aptr = new ExampleAdapter(MainActivity.this, cursor, alStoreNames); 
     searchView.setSuggestionsAdapter(aptr); 

    searchView.setOnQueryTextListener(new OnQueryTextListener() { 

     @Override 
     public boolean onQueryTextSubmit(String arg0) { 
      if (!TextUtils.isEmpty(arg0)) { 
       aptr.getFilter().filter(arg0.toString()); 
      } 
      return true; 
     } 

     @Override 
     public boolean onQueryTextChange(String arg0) { 
      return false; 
     } 
    }); 

    searchView.setOnSuggestionListener(new OnSuggestionListener() { 

      @Override 
      public boolean onSuggestionSelect(int arg0) { 
       return false; 
      } 

      @Override 
      public boolean onSuggestionClick(int position) { 
       String suggestion = getSuggestion(position); 
       db.openDatabase(); 
       String studentId = db.getStudentIdFromName(suggestion); 
       String studentImg = db.getStudentImgFromName(suggestion); 
       db.closeDatabase(); 
       Log.e("Sp", " On Click name -> " + aptr.getItem(position).toString() + " : " 
         + aptr.getCursor().getString(0) + " : " + suggestion); 
       Intent i = new Intent(MainActivity.this, 
         ExampleActivity.class); 
       i.putExtra("studentId", studentId); 
       i.putExtra("studentName", suggestion); 
       i.putExtra("studentImg", studentImg); 
       startActivity(i); 
       return true; 
      } 
     }); 

    return true; 
} 

private String getSuggestion(int position) { 
    Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem(
      position); 
    String suggest1 = cursor.getString(cursor.getColumnIndex("text")); 
    return suggest1; 
} 

private void setSearchTextColour(SearchView searchView) { 
     Field qTextField; 
     try { 
      qTextField = SearchView.class.getDeclaredField("mQueryTextView"); 
      qTextField.setAccessible(true); 
      SearchAutoComplete searchPlate = (SearchAutoComplete) qTextField 
        .get(searchView); 
      searchPlate.setTextColor(getResources().getColor(R.color.white)); 
     } catch (NoSuchFieldException e) { 
      e.printStackTrace(); 
     } 
     catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

private void setSearchIcons(SearchView searchView) { 
    try { 
     Field searchField = SearchView.class 
       .getDeclaredField("mCloseButton"); 
     searchField.setAccessible(true); 
     ImageView closeBtn = (ImageView) searchField.get(searchView); 
     closeBtn.setImageResource(R.drawable.close); 

     Field searchField1 = SearchView.class 
       .getDeclaredField("mSearchButton"); 
     searchField1.setAccessible(true); 
     ImageView searchButton = (ImageView) searchField1.get(searchView); 
     searchButton.setImageResource(R.drawable.ic_action_search); 

    } catch (NoSuchFieldException e) { 
     Log.e("SearchView", e.getMessage(), e); 
    } catch (IllegalAccessException e) { 
     Log.e("SearchView", e.getMessage(), e); 
    } 
} 
+0

更换过滤器代码 – Lokesh 2014-11-10 17:50:22

+0

什么样的变化?有没有过滤问题..问题是与onsuggestionclick – Lavanya 2014-11-11 05:08:14

+0

检查:http://stackoverflow.com/questions/23422072/searchview-in-listview-having-a-custom-adapter/23422665#23422665 – 2014-11-14 10:36:46

回答

2

在我看来,这个问题的一部分是在没有为getItem()方法。

如果您查看游标适配器源代码,getItem()将从游标中获取数据,而不是从过滤列表中获取数据,您希望它从过滤的列表中获取数据!

试试这个:

@Override 
public Object getItem(int position) { 
    if (position < items.size()) {    
     return items.get(position); 
    } else { 
     return null; 
    } 
} 

我忘了补充,你也需要改变这一点:

private String getSuggestion(int position) { 
    String suggest1 = (String) searchView.getSuggestionsAdapter().getItem(position);  
    return suggest1; 
} 

并关闭一切,首先添加这createOptions菜单:

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.main, menu); 
    MenuItem searchItem = menu.findItem(R.id.action_search); 
    searchView = (SearchView) MenuItemCompat.getActionView(searchItem); 

    searchView.setIconifiedByDefault(true); //this line 

    ... 

然后将此添加到onGuggestionClick:

@Override 
public boolean onSuggestionClick(int position) { 
    String suggestion = getSuggestion(position); 
    db.openDatabase(); 
    String studentId = db.getStudentIdFromName(suggestion); 
    String studentImg = db.getStudentImgFromName(suggestion); 
    db.closeDatabase(); 
    Log.e("Sp", " On Click name -> " + aptr.getItem(position).toString() + " : " 
     + aptr.getCursor().getString(0) + " : " + suggestion); 

    searchView.setIconified(true);//this line 


    Intent i = new Intent(MainActivity.this,ExampleActivity.class); 
    i.putExtra("studentId", studentId); 
    i.putExtra("studentName", suggestion); 
    i.putExtra("studentImg", studentImg); 
    startActivity(i); 
    return true; 
} 

有点解释。当您调用setIconified时,它将清除searchView的文本或将其折叠,具体取决于默认状态。我们在那里做的是将默认状态设置为图标化,所以当我们调用setIconified方法时,它将清除文本并折叠视图!

2

你好,我发现了一些问题与您的代码。 请尝试我的方式。 更换publishResults of ExampleAdapter

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

       items.clear(); 
       // items = new ArrayList<String>(); 
       //items = (ArrayList<String>) results.values; 
       items.addAll((ArrayList<String>) results.values); 
       notifyDataSetChanged(); 

      } 

searchView.setOnQueryTextListener(new OnQueryTextListener() { 

     @Override 
     public boolean onQueryTextSubmit(String arg0) { 
      if (!TextUtils.isEmpty(arg0)) { 
       aptr.getFilter().filter(arg0.toString()); 
      } 
      return true; 
     } 

     @Override 
     public boolean onQueryTextChange(String arg0) { 
if (!TextUtils.isEmpty(arg0)) { 
       aptr.getFilter().filter(arg0.toString()); 
return true; 
      } 
      return false; 
     } 
    }); 
+0

,解决了建议列表问题。但是,当我点击其中一个来自已排序建议列表的项目时,它指向该位置的旧字符串 – Lavanya 2014-11-10 07:50:49

+0

使cursoradapter全局并尝试使用adapter.getItem(position); – 2014-11-10 08:03:14

+0

我有onSuggestionClick,当我点击它给出点击字符串名称 – Lavanya 2014-11-10 10:08:28

0

尝试通过搜索值过滤,甚至是空的:

@Override 
public boolean onQueryTextSubmit(String arg0) { 
    aptr.getFilter().filter(arg0.toString()); 
    return true; 
} 

设置默认列表适配器如果搜索不匹配或搜索值为空:

@Override 
public Filter getFilter() { 
    return new Filter() { 
    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     constraint = constraint.toString().toLowerCase(); 
     FilterResults result = new FilterResults(); 

     if (constraint != null && constraint.toString().length() > 0) { 
      List<String> founded = new ArrayList<String>(); 
      for (int i = 0, l = orig.size(); i < l; i++) { 
       if (orig.get(i).toString().toLowerCase().startsWith(constraint.toString().toLowerCase())) 
          founded.add(orig.get(i)); 
      } 

      if(founded.size()>0){ 
      result.values = founded; 
      result.count = founded.size(); 
      }else{ 
      result.values = orig; 
      result.count = orig.size(); 
      } 
     } else { 
      result.values = orig; 
      result.count = orig.size(); 
     } 
     return result; 

}