Искать в RecyclerView с EditText

Я пишу этот код для поиска в recyclerview с текстом редактирования, но когда я запускаю приложение и ввожу текст, который мне нужно искать, в тексте редактирования в первой букве содержимое ресайклера не изменяется, и когда я ввожу вторую букву, RecyclerView станет пустым. как мне отфильтровать ресайклер? что не так в моем коде? xml-код:

<?xml version = "1.0" encoding = "utf-8"?>
<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    tools:context = ".FamilyActivity">

    <LinearLayout
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:orientation = "horizontal">

        <EditText
            android:id = "@+id/search"
            android:layout_width = "294dp"
            android:layout_height = "70dp"
            android:layout_marginTop = "-20dp"
            android:hint = "Search ..."
            android:drawableLeft = "@drawable/ic_search_black_24dp"
            />

        <Button
            android:id = "@+id/add"
            android:layout_width = "54dp"
            android:layout_height = "match_parent"
            android:layout_marginLeft = "35dp"
            android:drawableTop = "@drawable/ic_person_add_black_24dp"
            android:onClick = "add_new_family"
            tools:ignore = "OnClick" />
    </LinearLayout>



    <android.support.v7.widget.RecyclerView
        android:id = "@+id/recyclerView"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"


        android:layout_alignParentStart = "true"
        android:layout_alignParentLeft = "true"
        android:layout_alignParentTop = "true"
        android:layout_marginStart = "0dp"
        android:layout_marginLeft = "0dp"
        android:layout_marginTop = "50dp"></android.support.v7.widget.RecyclerView>

</RelativeLayout>

код в основной деятельности:

public class FamilyActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    FamilyAdapter familyAdapter;
    Button add_family;
    EditText search;

    List<Family> familyList;
    String patientID = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_family);
        add_family=(Button)findViewById(R.id.add);
        search =(EditText)findViewById(R.id.search);

        familyList = new ArrayList<>();
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            patientID = extras.getString("ID");
        }
        loadFamilyList();
        //adding some items to our list

        //creating recyclerView adapter
        FamilyAdapter adapter = new FamilyAdapter(this, familyList);

        //setting adapter to recyclerView
        recyclerView.setAdapter(adapter);

        addTextListener();

    }

public void addTextListener(){

        search.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {}

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence query, int start, int before, int count) {

                query = query.toString().toLowerCase();

                final List<Family> filteredList = new ArrayList<>();

                for (int i = 0; i < familyList.size(); i++) {

                    final String text = familyList.get(i).toString().toLowerCase();
                    if (text.contains(query)) {

                        filteredList.add(familyList.get(i));
                    }
                }

                recyclerView.setLayoutManager(new LinearLayoutManager(FamilyActivity.this));
                FamilyAdapter fadapter = new FamilyAdapter(FamilyActivity.this,filteredList);
                recyclerView.setAdapter(fadapter);
                fadapter.notifyDataSetChanged();  // data set changed
            }
        });
    }

код в адаптере:

public class FamilyAdapter extends RecyclerView.Adapter<FamilyAdapter.FamilyViewHolder> {

private Context context;
private List<Family> familyList;
private List<Family> familyListFull;

public FamilyAdapter(Context context, List<Family> familyList) {
    this.context = context;
    this.familyList = familyList;
    familyListFull=new ArrayList<>(familyList);
}

@NonNull
@Override
public FamilyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.list_layout, null);
    return new FamilyViewHolder(view);

}

@Override
public void onBindViewHolder(FamilyViewHolder familyViewHolder, final int position) {
    Family family = familyList.get(position);
    familyViewHolder.textViewTitle.setText(family.getName());
    familyViewHolder.familyLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: clicked on : " + familyList.get(position));
            String name = familyList.get(position).getName();
            String num = familyList.get(position).getNum();
            Intent intent = new Intent(context, Chatting.class);
            intent.putExtra("num", num);
            intent.putExtra("name", name);
            context.startActivity(intent);


        }
    });
    familyViewHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(context );
            builder.setTitle("Delete");
            builder.setMessage("Are you sure you want to delete this one ")
                    .setPositiveButton("YES", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            RemoveFamilyMember(position);
                        }
                    }).setNegativeButton("NO", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    builder.setCancelable(true);
                }
            });
            AlertDialog alert=builder.create();
            alert.show();


        }
    });


}
1
0
3 498
2

Ответы 2

вы можете попробовать что-то подобное. Я думаю, это может сработать, я не тестировал, но я думаю, что создание нового адаптера каждый раз, когда в edittext что-то есть, - плохая идея. и если вы вернетесь к точке, где запрос равен "" пустой строке, тогда вы должны сделать список fileterd обратно во весь список, который я не вставлял туда

public class FamilyActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    FamilyAdapter familyAdapter;
    Button add_family;
    EditText search;

    List<Family> familyList;
    List<Family> filteredList;
    String patientID = "";
    FamilyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_family);
        add_family=(Button)findViewById(R.id.add);
        search =(EditText)findViewById(R.id.search);

        familyList = new ArrayList<>();
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            patientID = extras.getString("ID");
        }
        loadFamilyList();
        filteredList = new ArrayList<>(familyList);
        //adding some items to our list

        //creating recyclerView adapter
        adapter = new FamilyAdapter(this, filteredList);

        //setting adapter to recyclerView
        recyclerView.setAdapter(adapter);

        addTextListener();

    }

public void addTextListener(){

        search.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {}

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence query, int start, int before, int count) {

                query = query.toString().toLowerCase();

                filteredList = new ArrayList<>();

                for (int i = 0; i < familyList.size(); i++) {

                    final String text = familyList.get(i).toString().toLowerCase();
                    if (text.contains(query)) {

                        filteredList.add(familyList.get(i));
                    }
                }
                                    recyclerView.removeAllViews();;
                                    adapter.notifyDataSetChanged();  // data set changed
            }
        });
    }

Спасибо за помощь, recyclerview больше не исчезает, но он не работает как фильтр для элементов, так как элементы остаются прежними. Можете ли вы помочь мне решить эту проблему?

Raghad Hussien 01.01.2019 06:50
editTextSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            filter(s.toString());

        }
    });
private void filter(String text) {
    ArrayList<Model> newList = new ArrayList<>();
    for (Model item : mModelList) {
        if (item.getTitle().contains(text)){
            newList.add(item);
        }
    }
    yourAdapter.setFilter(newList);
}

Другие вопросы по теме