user-56729194712
user-56729194712

Reputation: 5

How to implement multiple filters in SearchView using RecyclerView and CardView?

enter image description here

Hi everyone, I have created a project, shown link above. I have SearchView using RecyclerView and CardView, items are stored using ArrayList. I have two problems that i can't solve it, so please help me.

First, SearchView works but does not match between Name and ColorLike.

enter image description here

Secondly, I want to implement multiple filters in SearchView using Spinner for options, so I can search by Name or ColorLike. Is it possible?

enter image description here

Thanks in advance.

Here is my code.

Model.java

package com.example.myapplication;

public class Model {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Adapter.java

package com.example.myapplication;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Locale;

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

    private LayoutInflater inflater;
    private ArrayList<Model> searchResult;
    private ArrayList<Model> arraylist;

    public static String[] name;
    public static String[] colorlike;

    public Adapter(Context context, ArrayList<Model> searchResult) {
        inflater = LayoutInflater.from(context);
        this.searchResult = searchResult;
        this.arraylist = new ArrayList<Model>();
        this.arraylist.addAll(MainActivity.searchResult);
    }

    @Override
    public Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.cardview_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tvName.setText(searchResult.get(position).getName());
        holder.tvColorLike.setText(colorlike[position]);
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView tvColorLike;
        private TextView tvName;

        MyViewHolder(View itemView) {
            super(itemView);

            tvName = (TextView) itemView.findViewById(R.id.item_name);
            tvColorLike = (TextView) itemView.findViewById(R.id.item_colorlike);
        }
    }

    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        MainActivity.searchResult.clear();
        if (charText.length() == 0) {
            MainActivity.searchResult.addAll(arraylist);
        } else {
            for (Model model : arraylist) {
                if (model.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.searchResult.add(model);
                }
            }
        }
        notifyDataSetChanged();
    }
}

MainActivity.java

package com.example.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import java.util.ArrayList;

import static com.example.myapplication.Adapter.colorlike;
import static com.example.myapplication.Adapter.name;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {

    public static ArrayList<Model> searchResult;
    private Adapter adapter;
    private static final String[] paths = {"Filter by Name", "Filter by ColorLike"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);

        name = getResources().getStringArray(R.array.name);
        colorlike = getResources().getStringArray(R.array.colorlike);

        searchResult = populateList();
        adapter = new Adapter(getApplicationContext(), searchResult);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

        Spinner spinner = (Spinner) findViewById(R.id.spinner);
        final ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, paths);
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter2);
        spinner.setOnItemSelectedListener(this);
    }

    private ArrayList<Model> populateList() {
        ArrayList<Model> list = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            Model model = new Model();
            model.setName(name[i]);
            list.add(model);
        }
        return list;
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);

        final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                adapter.filter(newText);
                return false;
            }
        });

        return true;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        switch (position) {
            case 0:
                break;
            case 1:
                break;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
}

activity_main.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:gravity="end"
        android:orientation="horizontal"
        android:paddingBottom="5dp"
        android:paddingEnd="16dp"
        android:paddingRight="16dp"
        android:paddingTop="5dp">

        <Spinner
            android:id="@+id/spinner"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:popupBackground="@color/colorPrimary" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f7f7f7"
        android:orientation="horizontal"
        android:padding="5dp"
        android:weightSum="2">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="21dp"
            android:layout_weight="1"
            android:text="Name"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="26dp"
            android:layout_weight="1"
            android:text="ColorLike"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:paddingBottom="16dp"
        android:paddingTop="16dp"
        android:scrollbars="vertical" />
</LinearLayout>

cardview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_gravity="center"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    card_view:cardBackgroundColor="#fff">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:orientation="horizontal"
        android:weightSum="2">

        <TextView
            android:id="@+id/item_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:paddingLeft="10dp"
            android:paddingStart="10dp"
            android:text="name"
            android:textColor="#000"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/item_colorlike"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:paddingLeft="10dp"
            android:paddingStart="10dp"
            android:text="colorlike"
            android:textColor="#000"
            android:textSize="16sp" />

    </LinearLayout>
</android.support.v7.widget.CardView>

Upvotes: 0

Views: 5986

Answers (2)

Hp Developer
Hp Developer

Reputation: 1

Here is code with few modifications:

Model.java

public class Model {
private String name;
private String colorlike;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getColorlike() {
    return colorlike;
}

public void setColorlike(String colorlike) {
    this.colorlike = colorlike;
}}

Adapter.java

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

private LayoutInflater inflater;
private ArrayList<Model> searchResult;
private ArrayList<Model> arraylist;

public static String[] name;
public static String[] colorlike;

Adapter(Context context, ArrayList<Model> searchResult) {
    inflater = LayoutInflater.from(context);
    this.searchResult = searchResult;
    this.arraylist = new ArrayList<>();
    this.arraylist.addAll(MainActivity.searchResult);
}

@NonNull
@Override
public Adapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.cardview_item, parent, false);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    holder.tvName.setText(searchResult.get(position).getName());
    holder.tvColorLike.setText(searchResult.get(position).getColorlike());
}

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

class MyViewHolder extends RecyclerView.ViewHolder {

    private TextView tvColorLike;
    private TextView tvName;

    MyViewHolder(View itemView) {
        super(itemView);

        tvName = itemView.findViewById(R.id.item_name);
        tvColorLike = itemView.findViewById(R.id.item_colorlike);
    }
}

public void filter(String charText, boolean isFilterByName) {
    charText = charText.toLowerCase(Locale.getDefault());
    MainActivity.searchResult.clear();
    if (charText.length() == 0) {
        MainActivity.searchResult.addAll(arraylist);
    } else {
        if (isFilterByName) {
            for (Model model : arraylist) {
                if (model.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.searchResult.add(model);
                }
            }
        }else {
            for (Model model : arraylist) {
                if (model.getColorlike().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.searchResult.add(model);
                }
            }
        }
    }
    notifyDataSetChanged();
}}

MainActivity.java

public class MainActivity extends AppCompatActivity
    implements AdapterView.OnItemSelectedListener {

public static ArrayList<Model> searchResult;
private Adapter adapter;
private static final String[] paths = {"Filter by Name", "Filter by ColorLike"};

public boolean isFilterByName = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);

    name = getResources().getStringArray(R.array.name);
    colorlike = getResources().getStringArray(R.array.colorlike);

    searchResult = populateList();
    adapter = new Adapter(getApplicationContext(), searchResult);
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

    Spinner spinner = findViewById(R.id.spinner);
    final ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, paths);
    adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter2);
    spinner.setOnItemSelectedListener(this);
}

private ArrayList<Model> populateList() {
    ArrayList<Model> list = new ArrayList<>();
    for (int i = 0; i < 8; i++) {
        Model model = new Model();
        model.setName(name[i]);
        model.setColorlike(colorlike[i]);
        list.add(model);
    }
    return list;
}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);

    final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            adapter.filter(newText, isFilterByName);
            return false;
        }
    });

    return true;
}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    switch (position) {
        case 0:
            isFilterByName=true;
            break;
        case 1:
            isFilterByName=false;
            break;
    }
}

@Override
public void onNothingSelected(AdapterView<?> parent) {
}}

Upvotes: 0

Himanshu
Himanshu

Reputation: 91

If I am not wrong you want to search via both name and Color. just replace the

public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        MainActivity.searchResult.clear();
        if (charText.length() == 0) {
            MainActivity.searchResult.addAll(arraylist);
        } else {
            for (Model model : arraylist) {
                if (model.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.searchResult.add(model);
                }
            }
        }
        notifyDataSetChanged();
    }

with the following code,

public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        MainActivity.searchResult.clear();
        if (charText.length() == 0) {
            MainActivity.searchResult.addAll(arraylist);
        } else {
            for (Model model : arraylist) {
                if (model.getName().toLowerCase(Locale.getDefault()).contains(charText) || model.getColor().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.searchResult.add(model);
                }
            }
        }
        notifyDataSetChanged();
    }

This will help you search using both color and name. Also add a String Color with its getter in Model Class.

Also, you can use different method for filtering if you want to search individually for Color and name.

using the same process.

Upvotes: 2

Related Questions