Search code examples
javaandroidandroid-fragmentsandroid-recyclerviewsearchview

How to make SearchView with same RecyclerView?


I have some fragments within a RecyclerView which is added to the MainActivity body container. I have a fragment with toolbar and RecyclerView which is added to the MainActivity head container. I want to do a search on all elements of all RecyclerView and make setVisibility(View.GONE) for body container and setVisibility(View.VISIBLE) for head RecyclerView. I don’t understand how to make the search.

fragment_stations.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="LinearLayoutManager" />
</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/container_from_toolbar"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/main_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />

    </ScrollView>

</LinearLayout>

fragment_search.xml

<LinearLayout android:layout_height="wrap_content"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <include layout="@layout/toolbar_main"/>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewSearch"
        android:visibility="visible"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="LinearLayoutManager" />
</RelativeLayout>
</LinearLayout>

RecyclerStationAdapter.java(for body container)

public class RecyclerStationAdapter extends RecyclerView.Adapter<RecyclerStationAdapter.ViewHolder> {

    private LayoutInflater mLayoutInflater;
    private List<Station> mStations;
    private Context mContext;
    private static AnimatorHelper animatorHelper;

    public RecyclerStationAdapter(Context context, List<Station> stations) {
        this.mStations = stations;
        this.mLayoutInflater = LayoutInflater.from(context);
        mContext = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mLayoutInflater.inflate(R.layout.example_list_item_station, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
//        viewHolder.setIsRecyclable(false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        Station station = mStations.get(position);
        holder.textView.setText(station.getName());
//        holder.setIsRecyclable(false);
        Glide.with(mContext)
                .load(mStations.get(position).getImage())
                .error(R.drawable.ic_launcher_foreground)
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .into(holder.imageView);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createFirebaseReport(position);
                Log.d("debug", mStations.get(position).getName());

                Player player = new Player(mStations.get(position).getStream());
                player.start(mContext);


                startPlayerService();
                if (animatorHelper != null)
                animatorHelper.stopAnimation();
                animatorHelper = new AnimatorHelper(holder.playViewAnimation);
                animatorHelper.startAnimation();
                Log.d("anm", String.valueOf(holder.getItemId()));
            }

            private void startPlayerService() {
                Intent serviceIntent = new Intent(mContext, NotificationService.class);
                serviceIntent.setAction(Const.ACTION.STARTFOREGROUND_ACTION);
                mContext.startService(serviceIntent);
            }
        });

    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private void createFirebaseReport(int position) {
        FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(mContext);
        Bundle eventDetails = new Bundle();

        StringBuilder sb = new StringBuilder();
        sb.append(mStations.get(position).getName() + " : " + mStations.get(position).getStream());

        eventDetails.putString("station", sb.toString());
        firebaseAnalytics.logEvent("select_station", eventDetails);
    }

    @Override
    public int getItemCount() {
        return mStations.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        final ImageView imageView;
        final TextView textView;
        final AVLoadingIndicatorView playViewAnimation;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = (ImageView) itemView.findViewById(R.id.ivStation);
            textView = itemView.findViewById(R.id.tvStation);
            playViewAnimation = itemView.findViewById(R.id.playing_anim);
        }
    }
}

Solution

  • you can add getFilter() method on your Adapter class and onCreateOptionsMenu on your Fragment. Follow the following codes;

     @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
    
        inflater.inflate(R.menu.seach_menu, menu);
    
        MenuItem menuItem = menu.findItem(R.id.action_search);
    
        androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) menuItem.getActionView();
    
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
    
                return false;
            }
    
            @Override
            public boolean onQueryTextChange(String newText) {
    
                customAdapter_halal.getFilter().filter(newText);
                return false;
            }
        });
    }
    

    and

    public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> implements Filterable {
    private Context context;
    LayoutInflater layoutInflater;
    List<Model> modeller;
    List<Model> filteredModel;
    
    
    public CustomAdapter(Context context, List<Model> models) {
        this.context = context;
        this.modeller = models;
        this.filteredModel = models;  // bu sekilde ekliyoruz
    
    }
    
    
    @NonNull
    @Override
    public CustomAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        layoutInflater = LayoutInflater.from(context);
        View v = layoutInflater.inflate(R.layout.row_list, parent, false);
        return new ViewHolder(v);
    }
    
    @Override
    public void onBindViewHolder(@NonNull CustomAdapter.ViewHolder holder, int position) {
    
        holder.name.setText(filteredModel.get(position).getName());
        holder.packageName.setText(filteredModel.get(position).getPackageName());
        holder.developer.setText(filteredModel.get(position).getDeveloperName());
        holder.price.setText(filteredModel.get(position).getPrice() + " " + "€");
        holder.rating.setText(String.valueOf(filteredModel.get(position).getRatingValue()));
        Picasso.get().load(filteredModel.get(position).getIconUrl()).into(holder.image_icon);
    
        holder.linearLayout.setTag(holder);
    
        holder.linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ViewHolder viewHolder = (ViewHolder) v.getTag();
                int position = holder.getAdapterPosition();
    
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
                String pName = filteredModel.get(position).getPackageName();
                String sabit = "https://play.google.com/store/apps/details?id=";
                String uzanti = sabit + pName;
                intent.setData(Uri.parse(uzanti));
                context.startActivity(intent);
            }
        });
    
    }
    
    @Override
    public int getItemCount() {
        return filteredModel.size();
    }
    
    
    @Override
    public Filter getFilter() {
    
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
    
                String searchString = charSequence.toString();
                if (searchString.isEmpty()) {
    
                    filteredModel = modeller;
    
                } else {
    
                    ArrayList<Model> tempFilteredList = new ArrayList<>();
    
                    for (Model model : modeller) {
    
                        // search for user name
                        if (model.getName().toLowerCase().contains(searchString)) {
    
                            tempFilteredList.add(model);
                        }
                    }
                    filteredModel = tempFilteredList;
                }
    
                FilterResults filterResults = new FilterResults();
                filterResults.values = filteredModel;
                return filterResults;
            }
    
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                filteredModel = (ArrayList<Model>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }
    
    
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView name, packageName, developer, rating, price;
        LinearLayout linearLayout;
        ImageView image_icon;
    
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.text_name);
            packageName = itemView.findViewById(R.id.text_packagename);
            developer = itemView.findViewById(R.id.text_developer);
            rating = itemView.findViewById(R.id.text_rating);
            price = itemView.findViewById(R.id.text_price);
            image_icon = itemView.findViewById(R.id.image_icon);
    
            linearLayout = itemView.findViewById(R.id.linear_layout);
    
        }
    }
    

    }

    and the most important point is don't forget adding setHasOptionsMenu(true); on your oncreateview() method.