Использование функции поиска в RecyclerView и получение одного и того же результата для каждого действия

Я новичок в Java-программировании для Android. Я использую MVVM, и у меня есть метод поиска в моем DAO. когда я использую этот метод для поиска чего-либо в recyclerview, он работает нормально, и я могу обновлять, удалять и нажимать на результат поиска. Однако после этого, если я попытаюсь отредактировать или удалить элемент напрямую, после того, как я нажму кнопку обновления или удаления, появится слово, которое я искал.

Ниже мой метод поиска в DAO.

@Query("SELECT * FROM vocabularytable WHERE Vocabulary LIKE '%' ||:vocabulary || '%'  OR Definition LIKE '%' ||:vocabulary || '%'")
    LiveData<List<Vocabulary>> search(String vocabulary);


Вот мой RecyclerViewAdapter

public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.VIewHolder> {

    private final List<Vocabulary> vocabularyList; // Original list
    private final List<Vocabulary> displayList; // List used for displaying
    private final Context context;
    private final onVocabularyClickListener onVocabularyClickListener;

    public RecycleViewAdapter(List<Vocabulary> vocabularyList, Context context, onVocabularyClickListener onVocabularyClickListener) {
        this.vocabularyList = vocabularyList;
        this.displayList = new ArrayList<>(vocabularyList);
        this.context = context;
        this.onVocabularyClickListener = onVocabularyClickListener;
    }




    @NonNull
    @Override
    public RecycleViewAdapter.VIewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_vocabulary, parent, false);

        return new VIewHolder(view, onVocabularyClickListener);
    }

    @Override
    public void onBindViewHolder(@NonNull RecycleViewAdapter.VIewHolder holder, int position) {
        holder.vocabularyBind(displayList.get(position));
    }

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

    public class VIewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private final AppCompatTextView tvVocabulary;
        private final AppCompatTextView tvDefinition;
        private final AppCompatImageButton imgBtnEdit;
        private final AppCompatImageButton imgBtnDelete;
        onVocabularyClickListener onVocabularyClickListener;

        public VIewHolder(@NonNull View itemView, onVocabularyClickListener onVocabularyClickListener) {
            super(itemView);

            tvVocabulary = itemView.findViewById(R.id.tvVocabulary);
            tvDefinition = itemView.findViewById(R.id.tvDefinition);
            imgBtnEdit = itemView.findViewById(R.id.imgBtnEdit);
            imgBtnDelete = itemView.findViewById(R.id.imgBtnDelete);
            this.onVocabularyClickListener = onVocabularyClickListener;
            itemView.setOnClickListener(this);
            imgBtnEdit.setOnClickListener(this);
            imgBtnDelete.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {

            if (v.getId() == R.id.imgBtnEdit) {
                onVocabularyClickListener.onEditVocabularyClick(getAdapterPosition());
            } else if (v.getId() == R.id.imgBtnDelete) {
                onVocabularyClickListener.onDeleteVocabularyClick(getAdapterPosition());
            } else {
                onVocabularyClickListener.onVocabularyClick(getAdapterPosition());
            }
        }
        public void vocabularyBind(Vocabulary vocabulary) {


            tvVocabulary.setText(vocabulary.getVocabulary());

            tvDefinition.setText(vocabulary.getDefinition());
        }

    }

    public void filterList(List<Vocabulary> filteredList) {
            displayList.clear();
            displayList.addAll(filteredList);
            notifyDataSetChanged();
    }
    public void resetList(List<Vocabulary> originalList) {
        displayList.clear();
        displayList.addAll(originalList);
        notifyDataSetChanged();
    }



    public Vocabulary getVocabularyAtPosition(int position) {
        return displayList.get(position);

    }

    public interface onVocabularyClickListener {
        void onVocabularyClick(int position);

        void onDeleteVocabularyClick(int position);

        void onEditVocabularyClick(int position);

    }
}

И вот MainActivity (я использую текст редактирования для поиска

Здесь я загружаю дада в recyclerview, когда открываю приложение (вызываю этот метод в onCreate

private void recyclerLoad() {

        vocabularyViewModel = new ViewModelProvider.AndroidViewModelFactory(MainActivity.this.getApplication()).create(VocabularyViewModel.class);
        vocabularyViewModel.getAllData.observe(this, vocabularies -> {
            recycleViewAdapter = new RecycleViewAdapter(vocabularies, MainActivity.this, MainActivity.this);
            recyclerView.setAdapter(recycleViewAdapter);
        });
    }
searchView.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) {

                String query =s.toString();
                if (!query.isEmpty()) {
                    vocabularyViewModel.search(query).observe(MainActivity.this, (List<Vocabulary> list) -> {
                        recycleViewAdapter.filterList(list);
                    });
                } else {
                    searchView.clearFocus();
                    hideKeyboard(searchView);
                    refreshVocabularyList();
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

**Method for when I click on an item**

@Override
    public void onVocabularyClick(int position) {
        searchView.clearFocus();
        DialogFragment.isDelete = false;
        DialogFragment.isEdit = false;
        Vocabulary vocabulary = recycleViewAdapter.getVocabularyAtPosition(position);
        Bundle bundle = new Bundle();
        bundle.putParcelable("vocabulary", vocabulary);
        showFragment.setArguments(bundle);
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.mainLayout, showFragment)
                .addToBackStack(null)
                .commit();
    }

**For when I click on delete (imageButton) next to an item**

    @Override
    public void onDeleteVocabularyClick(int position) {
        searchView.clearFocus();
        DialogFragment.isEdit = false;
        DialogFragment.isDelete = true;
        Vocabulary vocabulary = recycleViewAdapter.getVocabularyAtPosition(position);
        Bundle bundle = new Bundle();
        bundle.putParcelable("vocabulary", vocabulary);
        dialogFragment.setArguments(bundle);
        dialogFragment.show(getSupportFragmentManager(), null);
    }

**When I click on edit (imageButton) next to an item**
    @Override
    public void onEditVocabularyClick(int position) {
        searchView.clearFocus();
        DialogFragment.isDelete = false;
        DialogFragment.isEdit = true;
        Vocabulary vocabulary = recycleViewAdapter.getVocabularyAtPosition(position);
        Bundle bundle = new Bundle();
        bundle.putParcelable("vocabulary", vocabulary);
        dialogFragment.setArguments(bundle);
        dialogFragment.show(getSupportFragmentManager(), null);

    }

**When I click on save button in a dialog to enter new words**
    @Override
    public void onDialogSave(Vocabulary vocabulary) {
        if (vocabulary != null) {
            searchView.clearFocus();
            VocabularyViewModel.insert(vocabulary);
            refreshVocabularyList(); // Refresh the list after saving
            dialogFragment.dismiss();
        }
    }


**When I click on update button in the update dialog**
    @Override
    public void onDialogUpdate(Vocabulary vocabulary) {
        if (vocabulary != null) {
            VocabularyViewModel.update(vocabulary);
            refreshVocabularyList(); //Refresh the list after updating
            dialogFragment.dismiss();
        } else {
            Toast.makeText(this, "Please fill all the fields", Toast.LENGTH_SHORT).show();
        }
    }

**When I click on delete button in the delete dialog**
    @Override
    public void onDialogDelete(Vocabulary vocabulary) {
        if (vocabulary != null) {
            VocabularyViewModel.delete(vocabulary);
            refreshVocabularyList(); //Refresh the list after deleting
            dialogFragment.dismiss();
        }
    }

    private void refreshVocabularyList() {
        vocabularyViewModel.getAllData.observe(MainActivity.this, vocabularies ->{
            /*vocabularyList.clear();
            vocabularyList.addAll(vocabularies);*/
            recycleViewAdapter.resetList(vocabularies); // Reset to original list
    });

    }

Сначала я ищу слово. оно отображается, и я могу нажать на него, отредактировать или удалить с этого момента, если я попытаюсь отредактировать или удалить слово прямо из списка (не ища его) , после того, как я это сделаю, оно отображается слово, которое есть в списке поиска, а не весь список или весь обновленный список, или теперь ничего не показывает. раньше показывалось слово, которое я искал

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что у вас есть случай, когда в текстовом поле не установлено значение "" после вашей модели VocabularyViewModel

Например

Добавьте этот фрагмент кода ниже ко всем вашим функциям, таким как onDialogUpdate, onDialogSave и onDialogDelete.

searchView.setText(""); // clears your search field

Внимательно изучаю документацию по Android android

Я думаю, нам нужно удалить наблюдаемое, прежде чем начинать новый поиск, это должно сработать.

searchView.addTextChangedListener(new TextWatcher() {
    private LiveData<List<Vocabulary>> searchLiveData;

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

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String query = s.toString();
        if (!query.isEmpty()) {
            if (searchLiveData != null) {
                // Remove the old observer before starting a new search
                searchLiveData.removeObservers(MainActivity.this);
            }
            searchLiveData = vocabularyViewModel.search(query);
            searchLiveData.observe(MainActivity.this, list -> {
                recycleViewAdapter.filterList(list);
            });
        } else {
            searchView.clearFocus();
            hideKeyboard(searchView);
            refreshVocabularyList();
        }
    }

    @Override
    public void afterTextChanged(Editable s) {}
});

Я это сделал, но это не работает. Я думаю, мне нужно где-то очистить или удалить список поиска, но я не знаю где.

Alex Nourani 20.08.2024 05:14

@AlexNourani попробуйте добавить это recycleViewAdapter.resetList(vocabularyViewModel.getAllData.‌​getValue()); после searchView..setText("")

Derek Roberts 20.08.2024 05:19

Я сейчас сделал, как вы сказали, не работает.

Alex Nourani 20.08.2024 07:19

это очень странно, часть меня думает о вашем database запросе, но я проведу расследование, как только узнаю, есть ли у вас какие-либо ошибки. Я обновил код, теперь посмотрим, что произойдет. @АлексНурани

Derek Roberts 20.08.2024 15:09

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

Alex Nourani 23.08.2024 02:27

@AlexNourani попробуйте изменить add searchView.addTextChangedListener и еще одну вещь, о которой я мог подумать, это то, что вы не закрываете соединение с базой данных после чтения из нее.

Derek Roberts 23.08.2024 06:55

@AlexNourani, можете ли вы изменить все вхождения строки на TextField, чтобы использовать экземпляр TextFieldValue вместо String. Пожалуйста, обратитесь за помощью к этой документации материал.mit.edu/afs/sipb/project/android/docs/guide/topics/ui/‌​…

Derek Roberts 23.08.2024 12:31

Я использую базу данных номеров. Нужно ли закрывать какое-либо соединение? Я прочту статью и попробую реализовать. Спасибо

Alex Nourani 25.08.2024 02:09

@AlexNourani о да, вы делаете, потому что, если вы этого не сделаете, ваша программа все равно будет использовать то же соединение, которое она использовала для чтения, а также для обновления/удаления, когда этого не следует, новое соединение должно быть установлено к базе данных для любой транзакции, а также recycleview устарел разработчик .android.com/reference/android/support/v7/widget/… почему вы не используете Jetpack Compose вместо традиционного XML, я думаю, что значение текстового поля в вашем случае не поддерживается, поэтому может не сработать.

Derek Roberts 25.08.2024 03:19

@AlexNourani Я обновил КОД. Похоже, что в вашем методе afterTextChanged нет непосредственной угрозы бесконечного цикла, поскольку вы не вносите изменения в Editable непосредственно внутри него. Однако если бы вы изменили Editable внутри afterTextChanged, вам нужно было бы быть осторожным, чтобы избежать рекурсивных вызовов. В нынешнем виде использование afterTextChanged безопасно.

Derek Roberts 25.08.2024 03:43

Дааа,-->> «Я думаю, нам нужно удалить наблюдаемое, прежде чем начинать новый поиск, это должно сработать» Вы правы. проблема была в этом, и я сделал то же самое внутри ondialogUpdate и onDialogeDelete. и это полностью работает. Большое спасибо. что касается jetCompose, мне нужно начать его изучать и работать с ним. Я считаю, что один лучше.

Alex Nourani 26.08.2024 05:01

@AlexNourani Я рад, что это работает

Derek Roberts 26.08.2024 05:02

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