首页 > 解决方案 > 向我的 RecyclerView 添加过滤/搜索

问题描述

我有一个完美运行的 RecyclverView 设置(它可能不是“最佳实践”,但它有效)

我实现的 RecyclerView 方法来自这个视频

为此,我做了以下事情:

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);
    }


}

标签: javaandroidfilterandroid-recyclerview

解决方案


这是一个示例,如何在 RecyclerView 上实现搜索过滤器。我将使用mImageNamesarrayList,我将在其上执行过滤器。我们需要做几件事。

(制作列表副本,实现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;
}

推荐阅读