마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

리사이클러뷰 그리드레이아웃 필터, 범주구현

0 추천

코딩을 시작한 지 이제 한 달 차예요.

인터넷 예제를 찾아보고 섞어가며 연습을 하고 있는데,

프레그먼트 안 리사이클러뷰에 필터 기능을 적용했지만 필터 기능이 작동하지 않네요...

오류는 뜨지 않고 정상작동하지만, 필터단어를 입력 시 리사이클러뷰가 출력이 되지 않아요!

 

 

추가로 필터와 별개로 카테고리 버튼으로 아이템을 분류하는 작업도 수행하고 싶지만

어떻게 구현을 해야할지 감이 잡히지 않네요...

 

필터기능을 텍스트서치가 아닌 버튼에 할당해서 카테고리별 분류로 하는 것이 나을까요..?

필터기능만 구글링하며 3일정도 필터만 가지고 고생했네요.... 도와주세요!

 

 

 

코드를 넣었다 뺏다 하면서 좀 지저분해졌네요...

 

 

리사이클러뷰 프레그먼트입니다.

import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

import java.util.ArrayList;


public class RecyclerViewTestFragment extends Fragment implements TextWatcher {

    ArrayList<Test> tests = new ArrayList<>();


    RecyclerView recyclerView_Test;

    EditText editText;
    TestAdapter adapter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v =  inflater.inflate(R.layout.fragment_recycler_view_test, container, false);


        recyclerView_Test = v.findViewById(R.id.rcv_Test);




        editText = v.findViewById(R.id.search_TextV);
        editText.addTextChangedListener(this);




        adapter = new TestAdapter(getContext(), tests);
        recyclerView_Test.setLayoutManager((new GridLayoutManager(getContext(),3)));
        recyclerView_Test.setAdapter(adapter);


        tests.add(new Test("item1","2",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템2","1",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템3","2",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템4","1",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템5","4",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템6","3",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템7","3",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템8","1",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템9","4",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템10","1",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템11","2",R.drawable.ic_launcher_background));
        tests.add(new Test("아이템12","1",R.drawable.ic_launcher_background));





        return v;
    }



    @Override
    public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
        adapter.getFilter().filter(charSequence);
    }

    @Override
    public void afterTextChanged(Editable editable) {


    }
}

 

 

어댑터입니다.


import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;



import java.util.ArrayList;


public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestItemViewHolder> implements Filterable {

    ArrayList<Test> tests;
    ArrayList<Test> filteredTests;

    Intent intent;
    Context context;



    public TestAdapter(Context context, ArrayList<Test> list){
        super();
        this.context = context;
        this.tests = list;
        this.filteredTests = list;
    }

    @NonNull
    @Override
    public TestItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.item_set,parent,false);
        return new TestItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TestItemViewHolder holder,int position) {
        holder.iV_1.setImageResource(filteredTests.get(position).getResId());
        holder.tV_1.setText(filteredTests.get(position).getItem1());

        holder.cDV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                intent = new Intent(v.getContext(),Clickintent.class);
                intent.putExtra("num",position);
                intent.putExtra("아이템",filteredTests.get(position).getItem1());
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                v.getContext().startActivity(intent);
            }
        });


    }

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





    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String charString = constraint.toString();
                if (charString.isEmpty()){
                    tests = filteredTests;
                } else {
                    ArrayList<Test> filteringList = new ArrayList<>();
                    for(Test item1 : tests) {
                        if (item1.getCategory().contains(charString)) {
                            filteringList.add(item1);
                        }
                    }
                    filteredTests = filteringList;
                }
                FilterResults filterResults = new FilterResults();
                filterResults.values = filteredTests;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                filteredTests = (ArrayList<Test>)results.values;
                notifyDataSetChanged();
            }
        };




    }

    public static class TestItemViewHolder extends RecyclerView.ViewHolder {
        public ImageView iV_1;
        public TextView tV_1;
        public CardView cDV;



        public TestItemViewHolder(View itemView){
            super(itemView);

            iV_1 = itemView.findViewById(R.id.iV1);
            tV_1 = itemView.findViewById(R.id.tV1);
            cDV = itemView.findViewById(R.id.cd_V);
        }


    }
}

 

 

아이템 클래스 입니다.

public class Test {

    private String item1;
    private String category;
    private int resId;

    public Test(String item1, String category, int resId) {
        this.item1 = item1;
        this.category = category;
        this.resId = resId;
    }

    public String getItem1() {
        return item1;
    }

    public void setItem1(String item1) {
        this.item1 = item1;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public int getResId() {
        return resId;
    }

    public void setResId(int resId) {
        this.resId = resId;
    }
}

 

 

 

 

awesomeBread (120 포인트) 님이 2021년 10월 2일 질문
앗... 지금 글을 작성한 후에 프레그먼트에서 "Button-1"에 "adapter.getFilter().filter("1")을 작성하고 실행해보니 해당하는 카테고리가 선별되어서 필터링 되었습니다!
아직 텍스트서치로 필터링하는 작업은 안되네요...
TextWatcher 메소드를 afterTextChanged로 사용해 보세요.
    @Override
    public void afterTextChanged(Editable editable) {
        adapter.getFilter().filter(editable.toString());
    }
다른 문제점이 있나 보네요.. 고맙습니다!
버튼을 누를 때랑 에디트 텍스트에 검색어를 입력할 때랑 필터가 다르게 적용되는 걸로 보이는데요. 버튼을 누를 때는
adapter.getFilter().filter("1")
이렇게 하드코딩을 했지만, 에디트 텍스트에 입력을 할 때는 사용자가 입력한대로 필터를 걸기 때문에 당연히 둘의 결과가 다르게 나오겠죠. 사용자 입력을 카테코리 코드로 변환하거나 카테고리 이름으로 해서 필터를 적용시키셔야 할 것 같은데요.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...