java - 向我的 RecyclerView 添加过滤/搜索
问题描述
我有一个完美运行的 RecyclverView 设置(它可能不是“最佳实践”,但它有效)
我实现的 RecyclerView 方法来自这个视频
为此,我做了以下事情:
- 我在
activity_main.xml
布局中添加了一个带有 id的 RecyclerView@+id/recycler_view
- 创建一个名为 RecyclerView Adapter 的类
RecyclerViewAdapter
- 创建一个名为的列表项布局
layout_listitem.xml
values
这完美地工作并从名为的 xml中提取信息sheep.xml
当您单击其中一个项目时,它会加载活动,该活动会在新布局GalleryActivity
中显示该项目位置的信息。activity_gallery.xml
下面的图像示例:
我想将过滤/搜索添加到我的 RecyclerView。我在网上遵循了许多来自不同人的指南,但仍然无法让它发挥作用。我创建了一个菜单布局,设置了一个可过滤的方法和一个“新列表”来存储过滤后的结果
有人可以帮我指出我可以在当前设置中使用的指南的正确方向吗?我的编码知识相当原始,所以请善待。
主要活动
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));
}
}
回收器视图适配器
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);
}
}
}
图库活动
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);
}
}
解决方案
这是一个示例,如何在 RecyclerView 上实现搜索过滤器。我将使用mImageNames
arrayList,我将在其上执行过滤器。我们需要做几件事。
(制作列表副本,实现Filterable
到您的适配器类,编写过滤器逻辑并将过滤后的值返回给您的 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);
} }
实现后Filterable
,您需要在适配器类中覆盖此方法。
@Override
public Filter getFilter() { return filter; }
之后,我们将编写执行过滤的逻辑。我正在考虑您的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();
}
};
适配器完成,现在回到 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>
现在我们将扩展菜单并将过滤器应用于您的适配器。
@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;
}
推荐阅读
- c# - 在谓词中动态选择参数的通用方法
- javascript - 识别元素中的随机背景梯度函数问题
- java - 等待多个线程完成
- python - python中的“具有多个元素的数组的真值不明确”
- python-3.x - Pandas 0.25.0 无法为 read_sql 创建游标 - 抛出错误
- javascript - 选择日期后模拟输入键(jquery)
- object-detection - 带有 TensorFlow Objection Detection API V2 的多通道输入
- linqpad - 以编程方式确定 linqpad 脚本是否针对生产连接字符串运行
- powershell - 如何创建签名自己的 exe/ps1 文件以与 applocker 一起使用
- visual-studio-2019 - “无法在设置文档缓冲区之前设置数据缓冲区。” 对于 IVsTextLines