本文翻译自:How to filter a RecyclerView with a SearchView
I am trying to implement the SearchView
from the support library. 我正在尝试从支持库实现SearchView
。 I want the user to be to use the SearchView
to filter a List
of movies in a RecyclerView
. 我希望用户使用SearchView
过滤RecyclerView
的电影List
。
I have followed a few tutorials so far and I have added the SearchView
to the ActionBar
, but I am not really sure where to go from here. 到目前为止我已经学过几个教程,我已经将SearchView
添加到ActionBar
,但我不确定从哪里开始。 I have seen a few examples but none of them show results as you start typing. 我看过几个例子,但是当你开始输入时,它们都没有显示结果。
This is my MainActivity
: 这是我的MainActivity
:
public class MainActivity extends ActionBarActivity {
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
RecyclerView.Adapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CardAdapter() {
@Override
public Filter getFilter() {
return null;
}
};
mRecyclerView.setAdapter(mAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And this is my Adapter
: 这是我的Adapter
:
public abstract class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> implements Filterable {
List<Movie> mItems;
public CardAdapter() {
super();
mItems = new ArrayList<Movie>();
Movie movie = new Movie();
movie.setName("Spiderman");
movie.setRating("92");
mItems.add(movie);
movie = new Movie();
movie.setName("Doom 3");
movie.setRating("91");
mItems.add(movie);
movie = new Movie();
movie.setName("Transformers");
movie.setRating("88");
mItems.add(movie);
movie = new Movie();
movie.setName("Transformers 2");
movie.setRating("87");
mItems.add(movie);
movie = new Movie();
movie.setName("Transformers 3");
movie.setRating("86");
mItems.add(movie);
movie = new Movie();
movie.setName("Noah");
movie.setRating("86");
mItems.add(movie);
movie = new Movie();
movie.setName("Ironman");
movie.setRating("86");
mItems.add(movie);
movie = new Movie();
movie.setName("Ironman 2");
movie.setRating("86");
mItems.add(movie);
movie = new Movie();
movie.setName("Ironman 3");
movie.setRating("86");
mItems.add(movie);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_view_card_item, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
Movie movie = mItems.get(i);
viewHolder.tvMovie.setText(movie.getName());
viewHolder.tvMovieRating.setText(movie.getRating());
}
@Override
public int getItemCount() {
return mItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView tvMovie;
public TextView tvMovieRating;
public ViewHolder(View itemView) {
super(itemView);
tvMovie = (TextView)itemView.findViewById(R.id.movieName);
tvMovieRating = (TextView)itemView.findViewById(R.id.movieRating);
}
}
}
#1楼
参考:https://stackoom.com/question/23XyJ/如何使用SearchView过滤RecyclerView
#2楼
Introduction 介绍
Since it is not really clear from your question what exactly you are having trouble with, I wrote up this quick walkthrough about how to implement this feature; 由于你的问题并不是很清楚你究竟遇到了什么问题,所以我写了一篇关于如何实现这个功能的快速演练。 if you still have questions feel free to ask. 如果你还有问题随时可以问。
I have a working example of everything I am talking about here in this GitHub Repository . 我在这个GitHub存储库中有一个我正在谈论的所有内容的工作示例。
If you want to know more about the example project visit the project homepage . 如果您想了解有关示例项目的更多信息,请访问项目主页 。
In any case the result should looks something like this: 在任何情况下,结果应如下所示:
If you first want to play around with the demo app you can install it from the Play Store: 如果您首先想要使用演示应用程序,可以从Play商店安装它:
Anyway lets get started. 无论如何让我们开始吧。
Setting up the SearchView
设置SearchView
In the folder res/menu
create a new file called main_menu.xml
. 在res/menu
文件夹中,创建一个名为main_menu.xml
的新文件。 In it add an item and set the actionViewClass
to android.support.v7.widget.SearchView
. 在其中添加一个项目并将actionViewClass
设置为android.support.v7.widget.SearchView
。 Since you are using the support library you have to use the namespace of the support library to set the actionViewClass
attribute. 由于您使用的是支持库,因此必须使用支持库的命名空间来设置actionViewClass
属性。 Your xml file should look something like this: 您的xml文件应如下所示:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
In your Fragment
or Activity
you have to inflate this menu xml like usual, then you can look for the MenuItem
which contains the SearchView
and implement the OnQueryTextListener
which we are going to use to listen for changes to the text entered into the SearchView
: 在你的Fragment
或Activity
你必须像往常一样膨胀这个菜单xml,然后你可以找到包含SearchView
的MenuItem
并实现OnQueryTextListener
,我们将用它来监听输入到SearchView
的文本的更改:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
// Here is where we are going to implement the filter logic
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
And now the SearchView
is ready to be used. 现在可以使用SearchView
。 We will implement the filter logic later on in onQueryTextChange()
once we are finished implementing the Adapter
. 稍后我们将在完成实现Adapter
之后在onQueryTextChange()
实现过滤器逻辑。
Setting up the Adapter
设置Adapter
First and foremost this is the model class I am going to use for this example: 首先,这是我将用于此示例的模型类:
public class ExampleModel {
private final long mId;
private final String mText;
public ExampleModel(long id, String text) {
mId = id;
mText = text;
}
public long getId() {
return mId;
}
public String getText() {
return mText;
}
}
It's just your basic model which will display a text in the RecyclerView
. 这只是您的基本模型,它将在RecyclerView
显示文本。 This is the layout I am going to use to display the text: 这是我将用于显示文本的布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="model"
type="com.github.wrdlbrnft.searchablerecyclerviewdemo.ui.models.ExampleModel"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true">
<TextView
android:layou