[英]Adding filtering/search to my RecyclerView
I have a RecyclverView set up which works perfectly (it may not be the 'best practice' but it works)我有一个完美运行的 RecyclverView 设置(它可能不是“最佳实践”,但它有效)
The RecyclerView method I implemented was from this video我实现的 RecyclerView 方法来自这个视频
For this I did the below:为此,我做了以下事情:
activity_main.xml
layout with an id @+id/recycler_view
activity_main.xml
布局中添加了一个 RecyclerView,其 ID 为@+id/recycler_view
RecyclerViewAdapter
RecyclerViewAdapter
的 RecyclerView 适配器 classlayout_listitem.xml
layout_listitem.xml
的列表项布局This worked perfectly and pulls the information from a values
xml called sheep.xml
这完美地工作并从名为
sheep.xml
的values
xml中提取信息
When you click on one of the items it loads activity GalleryActivity
which presents the information from that item position in a new activity_gallery.xml
layout.当您单击其中一个项目时,它会加载活动
GalleryActivity
,该活动在新的activity_gallery.xml
布局中显示来自该项目 position 的信息。
image examples below:下面的图像示例:
I want to add filtering/search to my RecyclerView.我想将过滤/搜索添加到我的 RecyclerView。 I have followed many guides online from various people and yet still can't get it to work.
我在网上遵循了许多来自不同人的指南,但仍然无法让它发挥作用。 I created a menu layouts, set up a filterable method and a 'new list' to store the filtered results
我创建了一个菜单布局,设置了一个可过滤的方法和一个“新列表”来存储过滤后的结果
Followed this this and this跟着这个这个和这个
Can someone please help me point me in the right direction of a guide I can use with my current set up.有人可以帮我指出我可以在当前设置中使用的指南的正确方向吗? I am fairly primitive in my coding knowledge so please be kind.
我的编码知识相当原始,所以请善待。
MainActivity主要活动
package com.british.sheep.breeds;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity{
String[ ] url;
String[ ] name;
String[ ] type;
String[ ] established;
String[ ] handle;
String[ ] colour;
String[ ] fleece;
String[ ] staple;
String[ ] micron;
String[ ] gallery;
private static final String TAG = "MainActivity";
//vars
private ArrayList<String> mNames = new ArrayList<>();
private ArrayList<String> mImageUrls = new ArrayList<>();
private ArrayList<String> mTypes = new ArrayList<>();
private ArrayList<String> mEstablisheds = new ArrayList<>();
private ArrayList<String> mHandles = new ArrayList<>();
private ArrayList<String> mColours = new ArrayList<>();
private ArrayList<String> mFleeces = new ArrayList<>();
private ArrayList<String> mStaples = new ArrayList<>();
private ArrayList<String> mMicrons = new ArrayList<>();
private ArrayList<String> mGalleryUrls = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
url = res.getStringArray( R.array.url ) ;
name = res.getStringArray( R.array.name ) ;
type = res.getStringArray( R.array.type ) ;
established = res.getStringArray( R.array.established ) ;
handle = res.getStringArray( R.array.handle ) ;
colour = res.getStringArray( R.array.colour ) ;
fleece = res.getStringArray( R.array.fleece ) ;
staple = res.getStringArray( R.array.staple ) ;
micron = res.getStringArray( R.array.micron ) ;
gallery = res.getStringArray( R.array.gallery ) ;
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
Log.d(TAG, "onCreate: started.");
initImageBitmaps();
}
private void initImageBitmaps(){
Log.d(TAG, "initImageBitmaps: preparing bitmaps.");
for (int i = 0; i < url.length; i++) {
mImageUrls.add(url[i]);
mNames.add(name[i]);
mTypes.add(type[i]);
mEstablisheds.add(established[i]);
mHandles.add(handle[i]);
mColours.add(colour[i]);
mFleeces.add(fleece[i]);
mStaples.add(staple[i]);
mMicrons.add(micron[i]);
mGalleryUrls.add(gallery[i]);
}
initRecyclerView();
}
private void initRecyclerView(){
Log.d(TAG, "initRecyclerView: init recyclerview.");
RecyclerView recyclerView = findViewById(R.id.recycler_view);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, mNames, mImageUrls, mTypes, mEstablisheds, mHandles, mColours, mFleeces, mStaples, mMicrons, mGalleryUrls);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
RecyclerViewAdapter回收器视图适配器
package com.british.sheep.breeds;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ArrayList<String> mImageNames = new ArrayList<>();
private ArrayList<String> mImages = new ArrayList<>();
private ArrayList<String> mImageTypes = new ArrayList<>();
private ArrayList<String> mImageEstablisheds = new ArrayList<>();
private ArrayList<String> mImageHandles = new ArrayList<>();
private ArrayList<String> mImageColours = new ArrayList<>();
private ArrayList<String> mImageFleeces = new ArrayList<>();
private ArrayList<String> mImageStaples = new ArrayList<>();
private ArrayList<String> mImageMicrons = new ArrayList<>();
private ArrayList<String> mImageGallerys = new ArrayList<>();
private Context mContext;
public RecyclerViewAdapter(Context context, ArrayList<String> imageNames, ArrayList<String> images, ArrayList<String> types, ArrayList<String> establisheds, ArrayList<String> handles, ArrayList<String> colours, ArrayList<String> fleeces, ArrayList<String> staples, ArrayList<String> microns ,ArrayList<String> gallerys ) {
mImageNames = imageNames;
mImages = images;
mImageTypes = types;
mImageEstablisheds = establisheds;
mImageHandles = handles;
mImageColours = colours;
mImageFleeces = fleeces;
mImageStaples = staples;
mImageMicrons = microns;
mImageGallerys = gallerys;
mContext = context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
Glide.with(mContext)
.asBitmap()
.load(mImages.get(position))
.into(holder.image);
holder.imageName.setText(mImageNames.get(position));
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, GalleryActivity.class);
intent.putExtra("image_url", mImages.get(position));
intent.putExtra("image_name", mImageNames.get(position));
intent.putExtra("image_type", mImageTypes.get(position));
intent.putExtra("image_established", mImageEstablisheds.get(position));
intent.putExtra("image_handle", mImageHandles.get(position));
intent.putExtra("image_colour", mImageColours.get(position));
intent.putExtra("image_fleece", mImageFleeces.get(position));
intent.putExtra("image_staple", mImageStaples.get(position));
intent.putExtra("image_micron", mImageMicrons.get(position));
intent.putExtra("image_gallery", mImageGallerys.get(position));
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mImageNames.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView imageName;
TextView imageType;
TextView imageEstablished;
TextView imageHandle;
TextView imageColour;
TextView imageFleece;
TextView imageStaple;
TextView imageMicron;
ImageView imageGallery;
RelativeLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
imageName = itemView.findViewById(R.id.image_name);
parentLayout = itemView.findViewById(R.id.parent_layout);
imageType = itemView.findViewById(R.id.image_type);
imageEstablished = itemView.findViewById(R.id.image_established);
imageHandle = itemView.findViewById(R.id.image_handle);
imageColour = itemView.findViewById(R.id.image_colour);
imageFleece = itemView.findViewById(R.id.image_fleece);
imageStaple = itemView.findViewById(R.id.image_staple);
imageMicron = itemView.findViewById(R.id.image_micron);
imageGallery = itemView.findViewById(R.id.image_gallery);
}
}
}
GalleryActivity图库活动
package com.british.sheep.breeds;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
public class GalleryActivity extends AppCompatActivity {
private static final String TAG = "GalleryActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
overridePendingTransition(R.anim.mtrl_bottom_sheet_slide_in, R.anim.mtrl_bottom_sheet_slide_out);
Log.d(TAG, "onCreate: started.");
getIncomingIntent();
}
@Override
public void onBackPressed() {
finishMyActivity();
}
public void finishMyActivity() {
finish();
overridePendingTransition(R.anim.mtrl_bottom_sheet_slide_in, R.anim.mtrl_bottom_sheet_slide_out);
}
private void getIncomingIntent() {
Log.d(TAG, "getIncomingIntent: checking for incoming intents.");
if (getIntent().hasExtra("image_url") && getIntent().hasExtra("image_name") && getIntent().hasExtra("image_type") && getIntent().hasExtra("image_established") && getIntent().hasExtra("image_handle") && getIntent().hasExtra("image_colour") && getIntent().hasExtra("image_fleece") && getIntent().hasExtra("image_staple") && getIntent().hasExtra("image_micron") && getIntent().hasExtra("image_gallery")) {
Log.d(TAG, "getIncomingIntent: found intent extras.");
String imageUrl = getIntent().getStringExtra("image_url");
String imageName = getIntent().getStringExtra("image_name");
String imageType = getIntent().getStringExtra("image_type");
String imageEstablished = getIntent().getStringExtra("image_established");
String imageHandle = getIntent().getStringExtra("image_handle");
String imageColour = getIntent().getStringExtra("image_colour");
String imageFleece = getIntent().getStringExtra("image_fleece");
String imageStaple = getIntent().getStringExtra("image_staple");
String imageMicron = getIntent().getStringExtra("image_micron");
String imageGallery = getIntent().getStringExtra("image_gallery");
setImage(imageUrl, imageName, imageType, imageEstablished, imageHandle, imageColour, imageFleece, imageStaple, imageMicron, imageGallery);
}
}
private void setImage(String imageUrl, String imageName, String imageType, String imageEstablished, String imageHandle, String imageColour, String imageFleece, String imageStaple, String imageMicron, String imageGallery) {
Log.d(TAG, "setImage: setting te image and name to widgets.");
//TextView name = findViewById(R.id.image_description);
//name.setText(imageName);
setTitle(imageName);
TextView type = findViewById(R.id.image_type);
type.setText(imageType);
TextView established = findViewById(R.id.image_established);
established.setText(imageEstablished);
TextView handle = findViewById(R.id.image_handle);
handle.setText(imageHandle);
TextView colour = findViewById(R.id.image_colour);
colour.setText(imageColour);
TextView fleece = findViewById(R.id.image_fleece);
fleece.setText(imageFleece);
TextView staple = findViewById(R.id.image_staple);
staple.setText(imageStaple);
TextView micron = findViewById(R.id.image_micron);
micron.setText(imageMicron);
ImageView gallery = findViewById(R.id.image_gallery);
Glide.with(this)
.asBitmap()
.load(imageGallery)
.into(gallery);
}
}
Here is an example, how you can implement a search filter on your RecyclerView.这是一个示例,如何在 RecyclerView 上实现搜索过滤器。 I am going to take
mImageNames
arrayList on which I'll perform the filter.我将使用
mImageNames
arrayList 来执行过滤器。 There are a couple of things we need to do.我们需要做几件事。
(Make a copy of list, Implement Filterable
to your adapter class, write filter logic and return the filtered value to your MainActivity class) (复制一份列表,将
Filterable
实现到您的适配器 class,编写过滤器逻辑并将过滤后的值返回给您的 MainActivity 类)
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements Filterable {
private ArrayList<String> mImageNames = new ArrayList<>();
private ArrayList<String> copyImageNames ;
public RecyclerViewAdapter (ArrayList<String> imageNames) {
mImageNames = imageNames;
copyImageNames = new ArrayList<>(imageNames);
} }
After your implement Filterable
you need to override this method inside your adapter class.实现
Filterable
后,您需要在适配器 class 中覆盖此方法。
@Override
public Filter getFilter() { return filter; }
After that we will write the logic to perform filter.I am considering that your mImageNames
list has name of all the sheeps (Balwen,Beltex.....) so that you can filter by their names.之后,我们将编写执行过滤器的逻辑。我正在考虑您的
mImageNames
列表具有所有绵羊的名称(Balwen,Beltex .....),以便您可以按它们的名称进行过滤。
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<String> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(copyImageNames );
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (String s : copyImageNames ) {
if (s.contains(filterPattern)) {
filteredList.add(s);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mImageNames .clear();
mImageNames .addAll((List) results.values);
notifyDataSetChanged();
}
};
Adapter is done, now back to MainActivity Create a menu directory under res folder and save this xml code.适配器完成,现在回到 MainActivity 在 res 文件夹下创建一个菜单目录并保存这个 xml 代码。
<?xml version="1.0" encoding="utf-8"?>
<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:icon="@drawable/ic_search"
android:title="Search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always|collapseActionView" /></menu>
Now we will inflate the menu and appply the filter to your adapter.现在我们将扩展菜单并将过滤器应用于您的适配器。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
MenuItem item =menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) item.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
return true;
}
First of all create in resources menu for your toolbar:首先在工具栏的资源菜单中创建:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_item_search"
android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_setSort"
android:icon="@drawable/ic_sort_off_24dp"
android:title="@string/routes_sort"
app:showAsAction="ifRoom" />
</menu>
add this line to one of items: app:actionViewClass="androidx.appcompat.widget.SearchView"
then in your activity with RecyclerView:将此行添加到项目之一:
app:actionViewClass="androidx.appcompat.widget.SearchView"
然后在您的活动中使用 RecyclerView:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.your_menu, menu);
MenuItem sortIcon = menu.findItem(R.id.menu_setSort);
MenuItem searchItem = menu.findItem(R.id.menu_item_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
Do not forget to implement this interface to your Activivty - implements SearchView.OnQueryTextListener
不要忘记为您的 Activivty 实现此接口 -
implements SearchView.OnQueryTextListener
Because of this interface you implemetnt this methods:由于这个接口,你实现了这个方法:
@Override
public boolean onQueryTextSubmit(String query) {
searchResult(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
You better make a class instead of all this ArrayLists:你最好制作一个 class 而不是所有这些 ArrayLists:
public class OneSheep {
private String mFleeces ;
private String mStaples ;
private String mMicrons ;
private String mGalleryUrls;
private String mNames;
private String mImageUrls ;
private String mTypes;
private String mEstablishedsist;
private String mHandles ;
private String mColours ;
public OneSheep(String names, String imageUrls, String types, String establishedsist, String handles, String colours, String fleeces, String staples, String microns, String galleryUrls) {
mNames = names;
mImageUrls = imageUrls;
mTypes = types;
mEstablishedsist = establishedsist;
mHandles = handles;
mColours = colours;
mFleeces = fleeces;
mStaples = staples;
mMicrons = microns;
mGalleryUrls = galleryUrls;
}
public String getNames() {
return mNames;
}
public String getImageUrls() {
return mImageUrls;
}
public String getTypes() {
return mTypes;
}
public String getEstablishedsist() {
return mEstablishedsist;
}
public String getHandles() {
return mHandles;
}
public String getColours() {
return mColours;
}
public String getFleeces() {
return mFleeces;
}
public String getStaples() {
return mStaples;
}
public String getMicrons() {
return mMicrons;
}
public String getGalleryUrls() {
return mGalleryUrls;
}
}
In your Activity make only one ArrayList<OneSheep> mSheeps
, pass it to your RecaclerView Adapter and this way it is gonna be mach easier to maintain that code.在您的 Activity 中只制作一个
ArrayList<OneSheep> mSheeps
,将其传递给您的 RecaclerView 适配器,这样维护该代码将变得更加容易。 Make your RecyclerView global for MainActivity, call it for example recyclerView and your searchResult()
method will look somethink like that:使您的 RecyclerView 全局用于 MainActivity,例如调用它 recyclerView 并且您的
searchResult()
方法看起来像这样:
private void searchResult(String query) {
ArrayList<OneSheep> newSheepsList = new ArrayList<>();
for (OneSheep sheep:mSheeps) {
if (sheep.getNames().contains(query)){
newSheepsList.add(sheep);
break;
}
if (sheep.getTypes().contains(query)){
newSheepsList.add(sheep);
break;
}
//add any conditions here
}
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, newSheepsList);
recyclerView.setAdapter(adapter);
}
Hope this helps希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.