SearchView 与 RecyclerView
SearchView with RecyclerView
一段时间以来,我一直在尝试将 SearchView 添加到我的 RecyclerView 中,并参考了这些帖子 , and 。在这一点上,我确信答案就在眼前。
但是,我不确定如何实现 SearchView,例如,使用以下内容:
private static final List<DataModel> getDummyData(){
List<DataModel> dummyDataList = new ArrayList<>();
dummyDataList.add(new DataModel("Alphabet", "Sub Alphabet"));
dummyDataList.add(new DataModel("Banana", "Sub Banana"));
dummyDataList.add(new DataModel("Captain", "Sub Captain"));
dummyDataList.add(new DataModel("Donut", "Sub Donut"));
dummyDataList.add(new DataModel("Elephant", "Sub Elephant"));
dummyDataList.add(new DataModel("Fox", "Sub Fox"));
dummyDataList.add(new DataModel("Giraffe", "Sub Giraffe"));
dummyDataList.add(new DataModel("Hippo", "Sub Hippo"));
dummyDataList.add(new DataModel("Iguana", "Sub Iguana"));
dummyDataList.add(new DataModel("Jumanji", "Sub Jumanji"));
return dummyDataList;
}
这是我当前的设置 (following this tutorial),它使用 Locale.getISOCountries();并搜索国家名称。
MainActivityFragment:
public class MainActivityFragment extends Fragment implements SearchView.OnQueryTextListener {
private RecyclerView mRecyclerView;
private List<DataModel> mDataModel;
private RVAdapter adapter;
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab_one_fragment, container, false);
mRecyclerView = (RecyclerView)view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(layoutManager);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
String[] locales = Locale.getISOCountries();
mDataModel = new ArrayList<>();
for (String countryCode : locales){
Locale obj = new Locale("", countryCode);
mDataModel.add(new DataModel(obj.getDisplayCountry(), obj.getISO3Country()));
}
adapter = new RVAdapter(mDataModel);
mRecyclerView.setAdapter(adapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(item,
new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
adapter.setFilter(mDataModel);
return true;
}
});
}
@Override
public boolean onQueryTextChange(String newText) {
final List<DataModel> filteredModeList = filter(mDataModel, newText);
adapter.setFilter(filteredModeList);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
private List<DataModel>filter(List<DataModel> models, String query){
query = query.toLowerCase();
final List<DataModel> filteredModeList = new ArrayList<>();
for (DataModel model : models){
final String text = model.getName().toLowerCase();
if (text.contains(query)){
filteredModeList.add(model);
}
}
return filteredModeList;
}
}
还有我的适配器-RVAdapter.java:
public class RVAdapter extends RecyclerView.Adapter<ItemViewHolder> {
private List<DataModel> mDataModel;
public RVAdapter(List<DataModel> mDataModel){
this.mDataModel = mDataModel;
}
@Override
public void onBindViewHolder(ItemViewHolder itemViewHolder, int position) {
final DataModel model = mDataModel.get(position);
itemViewHolder.bind(model);
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int position){
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, viewGroup, false);
return new ItemViewHolder(view);
}
@Override
public int getItemCount() {
return mDataModel.size();
}
public void setFilter(List<DataModel> dataModels){
mDataModel = new ArrayList<>();
mDataModel.addAll(dataModels);
notifyDataSetChanged();
}
}
这是ItemViewHolder.java:
public class ItemViewHolder extends RecyclerView.ViewHolder {
public TextView name_TextView;
public TextView subName_TextView;
public ItemViewHolder(View itemView){
super(itemView);
name_TextView = (TextView)itemView.findViewById(R.id.country_name);
subName_TextView = (TextView)itemView.findViewById(R.id.country_iso);
}
public void bind(DataModel dataModel){
name_TextView.setText(dataModel.getName());
subName_TextView.setText(dataModel.getSubName());
}
}
最后,DataModel.java:
public class DataModel {
String name;
String subName;
DataModel(String name, String subName){
this.name = name;
this.subName = subName;
}
public String getName(){
return name;
}
public String getSubName(){
return subName;
}
}
任何帮助、建议或指向正确方向的观点都会很棒!
这受到以下启发post:
我需要一个更复杂的解决方案,因为 recyclerview 托管在片段中,所以我使用 EventBus 将搜索查询从托管搜索视图的 activity 传递到片段。
来自有权访问 SearchView 的 Activity
@Override
public boolean onQueryTextChange(String query) {
EventBus.getDefault().post(new SearchEvent(query));
return true;
}
在托管 recyclerview 的片段上:
public void onEvent(SearchEvent e) {
final List<? extends GenericCompany> filteredModelList = filter(mCompanies, e.getSearchString());
mListAdapter.replaceData(filteredModelList);
mRecyclerView.scrollToPosition(0);
}
private List<? extends GenericCompany> filter(List<SCSponsors> models, String query) {
query = query.toLowerCase();
final List<SCSponsors> filteredModelList = new ArrayList<>();
for (SCSponsors model : models) {
final String text = model.getDisplayName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
适配器内部:
public void replaceData(List<? extends GenericCompany> companies) {
setList(companies);
notifyDataSetChanged();
}
好吧,所以在仔细查看 post 之后(这个答案在很大程度上基于并且离不开它),我最终得出以下结论:
注意:我最初在一个有 TabLayout 的项目上对此进行了测试,因此有一些与选项卡相关的变量和 class 名称。此外,我所有的布局都与上面链接的 post 中的布局相同,但是将它与 TabLayout、CoordinatorLayout/AppBarLayout 等一起使用应该不难。
这里是MainFragment.java
public class MainFragment extends Fragment implements SearchView.OnQueryTextListener {
public static MainFragment newInstance() {
return new MainFragment();
}
RecyclerView mRecyclerView;
private List<MemberData> tabListItem;
private RecyclerViewTabsAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.recyclerview, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setHasFixedSize(true);
tabListItem = new ArrayList<>();
tabListItem = getTabRowList();
mAdapter = new RecyclerViewTabsAdapter(getActivity(), tabListItem);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
final List<MemberData> filteredModelList = filter(tabListItem, newText);
mAdapter.animateTo(filteredModelList);
mRecyclerView.scrollToPosition(0);
return true;
}
private List<MemberData> filter(List<MemberData> datas, String newText) {
newText = newText.toLowerCase();
final List<MemberData> filteredModelList = new ArrayList<>();
for (MemberData data : datas) {
final String text = data.getName().toLowerCase();
if (text.contains(newText)) {
filteredModelList.add(data);
}
}
return filteredModelList;
}
private List<MemberData> getTabRowList() {
List<MemberData> currentItem = new ArrayList<>();
currentItem.add(new MemberData("Albert", "Albert Sub", R.drawable.your_drawable));
currentItem.add(new MemberData("Abby", "Abby Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Brian", "Brian Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Chris", "Chris Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Dante", "Dante Text", R.drawable.your_drawable));
//Add more of your dummy data here
return currentItem;
}
}
和适配器:
public class RecyclerViewTabsAdapter extends RecyclerView.Adapter<RecyclerViewTabsViewHolder> {
private final LayoutInflater mInflater;
private final List<MemberData>mItemList;
public RecyclerViewTabsAdapter(Context context, List<MemberData> itemList) {
mInflater = LayoutInflater.from(context);
mItemList = new ArrayList<>(itemList);
}
@Override
public RecyclerViewTabsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = mInflater.inflate(R.layout.cardview_detail, parent, false);
return new RecyclerViewTabsViewHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerViewTabsViewHolder holder, final int position) {
final MemberData data = mItemList.get(position);
holder.bind(data);
//TODO: Set onClick here
}
@Override
public int getItemCount() {
return this.mItemList.size();
}
public void animateTo(List<MemberData> memberDatas) {
applyAndAnimateRemovals(memberDatas);
applyAndAnimateAdditions(memberDatas);
applyAndAnimateMovedItems(memberDatas);
}
private void applyAndAnimateRemovals(List<MemberData> newDatas) {
for (int i = mItemList.size() - 1; i >= 0; i--) {
final MemberData data = mItemList.get(i);
if (!newDatas.contains(data)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<MemberData> newDatas) {
for (int i = 0, count = newDatas.size(); i < count; i++) {
final MemberData data = newDatas.get(i);
if (!mItemList.contains(data)) {
addItem(i, data);
}
}
}
private void applyAndAnimateMovedItems(List<MemberData> newDatas) {
for (int toPosition = newDatas.size() - 1; toPosition >= 0; toPosition--) {
final MemberData data = newDatas.get(toPosition);
final int fromPosition = mItemList.indexOf(data);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public MemberData removeItem(int position) {
final MemberData data = mItemList.remove(position);
notifyItemRemoved(position);
return data;
}
public void addItem(int position, MemberData data) {
mItemList.add(position, data);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final MemberData data = mItemList.remove(fromPosition);
mItemList.add(toPosition, data);
notifyItemMoved(fromPosition, toPosition);
}
}
和ViewHolder
public class RecyclerViewTabsViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView name;
TextView subText;
ImageView memberPhoto;
public RecyclerViewTabsViewHolder(View itemView){
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
name = (TextView)itemView.findViewById(R.id.person_name);
subText = (TextView)itemView.findViewById(R.id.person_subtext);
memberPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
}
public void bind(MemberData data){
name.setText(data.getName());
subText.setText(data.getSubText());
memberPhoto.setImageResource(data.getPhotoId());
}
}
最后,MemberData.java
public class MemberData {
String name;
String subText;
int photoId;
public MemberData(String name, String subText, int photoId){
this.name = name;
this.subText = subText;
this.photoId = photoId;
}
public String getName(){
return name;
}
public String getSubText() {
return subText;
}
public int getPhotoId() {
return photoId;
}
}
唯一剩下的问题(我会把它留到另一个 post),是 onClick 方法和在过滤列表后获得正确的位置。
希望对您有所帮助!
在您的适配器中 class 实现 filterable 并覆盖它的方法。
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if(charSequence == null | charSequence.length() == 0){
filterResults.count = getUserModelListFiltered.size();
filterResults.values = getUserModelListFiltered;
}else{
String searchChr = charSequence.toString().toLowerCase();
List<UserModel> resultData = new ArrayList<>();
for(UserModel userModel: getUserModelListFiltered){
if(userModel.getUserName().toLowerCase().contains(searchChr)){
resultData.add(userModel);
}
}
filterResults.count = resultData.size();
filterResults.values = resultData;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
userModelList = (List<UserModel>) filterResults.values;
notifyDataSetChanged();
}
};
return filter;
}
在您的 activity 中创建搜索视图并监听 setOnQueryTextListener。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem menuItem = menu.findItem(R.id.search_view);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
usersAdapter.getFilter().filter(newText);
return true;
}
});
return true;
}
完整教程和源代码:
Recyclerview with search view
一段时间以来,我一直在尝试将 SearchView 添加到我的 RecyclerView 中,并参考了这些帖子
但是,我不确定如何实现 SearchView,例如,使用以下内容:
private static final List<DataModel> getDummyData(){
List<DataModel> dummyDataList = new ArrayList<>();
dummyDataList.add(new DataModel("Alphabet", "Sub Alphabet"));
dummyDataList.add(new DataModel("Banana", "Sub Banana"));
dummyDataList.add(new DataModel("Captain", "Sub Captain"));
dummyDataList.add(new DataModel("Donut", "Sub Donut"));
dummyDataList.add(new DataModel("Elephant", "Sub Elephant"));
dummyDataList.add(new DataModel("Fox", "Sub Fox"));
dummyDataList.add(new DataModel("Giraffe", "Sub Giraffe"));
dummyDataList.add(new DataModel("Hippo", "Sub Hippo"));
dummyDataList.add(new DataModel("Iguana", "Sub Iguana"));
dummyDataList.add(new DataModel("Jumanji", "Sub Jumanji"));
return dummyDataList;
}
这是我当前的设置 (following this tutorial),它使用 Locale.getISOCountries();并搜索国家名称。
MainActivityFragment:
public class MainActivityFragment extends Fragment implements SearchView.OnQueryTextListener {
private RecyclerView mRecyclerView;
private List<DataModel> mDataModel;
private RVAdapter adapter;
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab_one_fragment, container, false);
mRecyclerView = (RecyclerView)view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(layoutManager);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
String[] locales = Locale.getISOCountries();
mDataModel = new ArrayList<>();
for (String countryCode : locales){
Locale obj = new Locale("", countryCode);
mDataModel.add(new DataModel(obj.getDisplayCountry(), obj.getISO3Country()));
}
adapter = new RVAdapter(mDataModel);
mRecyclerView.setAdapter(adapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(item,
new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
adapter.setFilter(mDataModel);
return true;
}
});
}
@Override
public boolean onQueryTextChange(String newText) {
final List<DataModel> filteredModeList = filter(mDataModel, newText);
adapter.setFilter(filteredModeList);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
private List<DataModel>filter(List<DataModel> models, String query){
query = query.toLowerCase();
final List<DataModel> filteredModeList = new ArrayList<>();
for (DataModel model : models){
final String text = model.getName().toLowerCase();
if (text.contains(query)){
filteredModeList.add(model);
}
}
return filteredModeList;
}
}
还有我的适配器-RVAdapter.java:
public class RVAdapter extends RecyclerView.Adapter<ItemViewHolder> {
private List<DataModel> mDataModel;
public RVAdapter(List<DataModel> mDataModel){
this.mDataModel = mDataModel;
}
@Override
public void onBindViewHolder(ItemViewHolder itemViewHolder, int position) {
final DataModel model = mDataModel.get(position);
itemViewHolder.bind(model);
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int position){
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, viewGroup, false);
return new ItemViewHolder(view);
}
@Override
public int getItemCount() {
return mDataModel.size();
}
public void setFilter(List<DataModel> dataModels){
mDataModel = new ArrayList<>();
mDataModel.addAll(dataModels);
notifyDataSetChanged();
}
}
这是ItemViewHolder.java:
public class ItemViewHolder extends RecyclerView.ViewHolder {
public TextView name_TextView;
public TextView subName_TextView;
public ItemViewHolder(View itemView){
super(itemView);
name_TextView = (TextView)itemView.findViewById(R.id.country_name);
subName_TextView = (TextView)itemView.findViewById(R.id.country_iso);
}
public void bind(DataModel dataModel){
name_TextView.setText(dataModel.getName());
subName_TextView.setText(dataModel.getSubName());
}
}
最后,DataModel.java:
public class DataModel {
String name;
String subName;
DataModel(String name, String subName){
this.name = name;
this.subName = subName;
}
public String getName(){
return name;
}
public String getSubName(){
return subName;
}
}
任何帮助、建议或指向正确方向的观点都会很棒!
这受到以下启发post:
我需要一个更复杂的解决方案,因为 recyclerview 托管在片段中,所以我使用 EventBus 将搜索查询从托管搜索视图的 activity 传递到片段。
来自有权访问 SearchView 的 Activity
@Override
public boolean onQueryTextChange(String query) {
EventBus.getDefault().post(new SearchEvent(query));
return true;
}
在托管 recyclerview 的片段上:
public void onEvent(SearchEvent e) {
final List<? extends GenericCompany> filteredModelList = filter(mCompanies, e.getSearchString());
mListAdapter.replaceData(filteredModelList);
mRecyclerView.scrollToPosition(0);
}
private List<? extends GenericCompany> filter(List<SCSponsors> models, String query) {
query = query.toLowerCase();
final List<SCSponsors> filteredModelList = new ArrayList<>();
for (SCSponsors model : models) {
final String text = model.getDisplayName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
适配器内部:
public void replaceData(List<? extends GenericCompany> companies) {
setList(companies);
notifyDataSetChanged();
}
好吧,所以在仔细查看 post
注意:我最初在一个有 TabLayout 的项目上对此进行了测试,因此有一些与选项卡相关的变量和 class 名称。此外,我所有的布局都与上面链接的 post 中的布局相同,但是将它与 TabLayout、CoordinatorLayout/AppBarLayout 等一起使用应该不难。
这里是MainFragment.java
public class MainFragment extends Fragment implements SearchView.OnQueryTextListener {
public static MainFragment newInstance() {
return new MainFragment();
}
RecyclerView mRecyclerView;
private List<MemberData> tabListItem;
private RecyclerViewTabsAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.recyclerview, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setHasFixedSize(true);
tabListItem = new ArrayList<>();
tabListItem = getTabRowList();
mAdapter = new RecyclerViewTabsAdapter(getActivity(), tabListItem);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
final List<MemberData> filteredModelList = filter(tabListItem, newText);
mAdapter.animateTo(filteredModelList);
mRecyclerView.scrollToPosition(0);
return true;
}
private List<MemberData> filter(List<MemberData> datas, String newText) {
newText = newText.toLowerCase();
final List<MemberData> filteredModelList = new ArrayList<>();
for (MemberData data : datas) {
final String text = data.getName().toLowerCase();
if (text.contains(newText)) {
filteredModelList.add(data);
}
}
return filteredModelList;
}
private List<MemberData> getTabRowList() {
List<MemberData> currentItem = new ArrayList<>();
currentItem.add(new MemberData("Albert", "Albert Sub", R.drawable.your_drawable));
currentItem.add(new MemberData("Abby", "Abby Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Brian", "Brian Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Chris", "Chris Text", R.drawable.your_drawable));
currentItem.add(new MemberData("Dante", "Dante Text", R.drawable.your_drawable));
//Add more of your dummy data here
return currentItem;
}
}
和适配器:
public class RecyclerViewTabsAdapter extends RecyclerView.Adapter<RecyclerViewTabsViewHolder> {
private final LayoutInflater mInflater;
private final List<MemberData>mItemList;
public RecyclerViewTabsAdapter(Context context, List<MemberData> itemList) {
mInflater = LayoutInflater.from(context);
mItemList = new ArrayList<>(itemList);
}
@Override
public RecyclerViewTabsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = mInflater.inflate(R.layout.cardview_detail, parent, false);
return new RecyclerViewTabsViewHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerViewTabsViewHolder holder, final int position) {
final MemberData data = mItemList.get(position);
holder.bind(data);
//TODO: Set onClick here
}
@Override
public int getItemCount() {
return this.mItemList.size();
}
public void animateTo(List<MemberData> memberDatas) {
applyAndAnimateRemovals(memberDatas);
applyAndAnimateAdditions(memberDatas);
applyAndAnimateMovedItems(memberDatas);
}
private void applyAndAnimateRemovals(List<MemberData> newDatas) {
for (int i = mItemList.size() - 1; i >= 0; i--) {
final MemberData data = mItemList.get(i);
if (!newDatas.contains(data)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<MemberData> newDatas) {
for (int i = 0, count = newDatas.size(); i < count; i++) {
final MemberData data = newDatas.get(i);
if (!mItemList.contains(data)) {
addItem(i, data);
}
}
}
private void applyAndAnimateMovedItems(List<MemberData> newDatas) {
for (int toPosition = newDatas.size() - 1; toPosition >= 0; toPosition--) {
final MemberData data = newDatas.get(toPosition);
final int fromPosition = mItemList.indexOf(data);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public MemberData removeItem(int position) {
final MemberData data = mItemList.remove(position);
notifyItemRemoved(position);
return data;
}
public void addItem(int position, MemberData data) {
mItemList.add(position, data);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final MemberData data = mItemList.remove(fromPosition);
mItemList.add(toPosition, data);
notifyItemMoved(fromPosition, toPosition);
}
}
和ViewHolder
public class RecyclerViewTabsViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView name;
TextView subText;
ImageView memberPhoto;
public RecyclerViewTabsViewHolder(View itemView){
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
name = (TextView)itemView.findViewById(R.id.person_name);
subText = (TextView)itemView.findViewById(R.id.person_subtext);
memberPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
}
public void bind(MemberData data){
name.setText(data.getName());
subText.setText(data.getSubText());
memberPhoto.setImageResource(data.getPhotoId());
}
}
最后,MemberData.java
public class MemberData {
String name;
String subText;
int photoId;
public MemberData(String name, String subText, int photoId){
this.name = name;
this.subText = subText;
this.photoId = photoId;
}
public String getName(){
return name;
}
public String getSubText() {
return subText;
}
public int getPhotoId() {
return photoId;
}
}
唯一剩下的问题(我会把它留到另一个 post),是 onClick 方法和在过滤列表后获得正确的位置。
希望对您有所帮助!
在您的适配器中 class 实现 filterable 并覆盖它的方法。
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if(charSequence == null | charSequence.length() == 0){
filterResults.count = getUserModelListFiltered.size();
filterResults.values = getUserModelListFiltered;
}else{
String searchChr = charSequence.toString().toLowerCase();
List<UserModel> resultData = new ArrayList<>();
for(UserModel userModel: getUserModelListFiltered){
if(userModel.getUserName().toLowerCase().contains(searchChr)){
resultData.add(userModel);
}
}
filterResults.count = resultData.size();
filterResults.values = resultData;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
userModelList = (List<UserModel>) filterResults.values;
notifyDataSetChanged();
}
};
return filter;
}
在您的 activity 中创建搜索视图并监听 setOnQueryTextListener。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem menuItem = menu.findItem(R.id.search_view);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
usersAdapter.getFilter().filter(newText);
return true;
}
});
return true;
}
完整教程和源代码: Recyclerview with search view