Живой поиск с использованием ListView

Нужна помощь с "живым поиском". Код в MainActivity:

ActivityMainBinding binding;
String[] items;
ArrayList<String> listItems;
ArrayAdapter<String> adapter;
ListView listView;
EditText editText;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    listView=(ListView)findViewById(R.id.listview);
    editText=(EditText)findViewById(R.id.psalmsearch);
    initList();

    editText.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) {
            if(s.toString().equals("")){
                // reset listview
                initList();
            } else {
                // perform search
                searchItem(s.toString());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }

    });

}
public void searchItem(String textToSearch){
    for(String item:items){
        String textToSearch1 = textToSearch.toLowerCase();
        if(!item.toLowerCase().contains(textToSearch1)){
            listItems.remove(item);
        }
    }
    adapter.notifyDataSetChanged();
}
public void initList(){


    String idpsalm[]  = {"1","2","3"};
    String[] namePsalm = {"1 текст номер 1","2 текст номер 2","3 текст номер 3"};
    String[] psalm = {"описание текста 1","описание текста 2","описание текста 3"};
    ArrayList<User> userArrayList = new ArrayList<>();
    for(int i = 0;i< idpsalm.length;i++){
        User user = new User(idpsalm[i], namePsalm[i],psalm[i]);
        userArrayList.add(user);
    }
   
    items=namePsalm;
    listItems=new ArrayList<>(Arrays.asList(items));
    adapter=new ArrayAdapter<String>(this, R.layout.list_item, R.id.name_psalms, listItems);
    listView.setAdapter(adapter);



    
    ListAdapter listAdapter = new ListAdapter(MainActivity.this,userArrayList);

    binding.listview.setAdapter(listAdapter);
    binding.listview.setClickable(true);
    binding.listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Intent i = new Intent(MainActivity.this,UserActivity.class);
            i.putExtra("idpsalm", idpsalm[position]);
            i.putExtra("namePsalm",namePsalm[position]);
            i.putExtra("psalm",psalm[position]);
            startActivity(i);
        }

    });


}

activity_main.xml:

     <EditText
    android:id="@+id/txtsearch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Пошук..."
    tools:ignore="MissingConstraints" />
<ListView
    android:id="@+id/listview"
    android:layout_below="@+id/txtsearch"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="30dp"
    android:keepScreenOn="true"
    tools:listitem="@layout/list_item" />

Не могу понять, как внедрить код поиска в мой код. Получается, что у меня ListView "переписывает друг друга".


Ответы (2 шт):

Автор решения: Denis Igorevich

Как вариант можешь попробовать такой способ

public void searchItem(String textToSearch){
    List<String> foundItems = new ArrayList<>();
    for(String item:itmes){
        String textToSearch1 = textToSearch.toLowerCase();
        if(!item.toLowerCase().contains(textToSearch1)){
            listItems.remove(item);
        }
    }
    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, foundItems);
    ListView listView = findViewById(R.id.list_item);
    listView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}

Возможно придется немного подредактировать, но думаю ты справишься. Идея в том, чтобы генерировать новый список, из результатов поиска. И тогда событие которые ты повесил на изменения текста в поле ввода, будет вызывать эту функцию, которая и будет заполнять новый список, а если поле ввода пустое, то заполняться список будет через функцию initList и соответственно будут выведены все элементы.

→ Ссылка
Автор решения: Eugene Pr

пол дня не могу сделать. уже решил брать с одного массива(хоть это немного не так, как мне нужно).

public void initList(){
    String[] psalm = getResources().getStringArray(R.array.psalm);
    items=psalm;
    listItems=new ArrayList<>(Arrays.asList(items));
    adapter=new ArrayAdapter<String>(this, R.layout.list_item, 
R.id.name_psalms, listItems);

    listView.setAdapter(adapter);
    listView.setClickable(true);
    listView.setOnItemClickListener((parent, view, position, id) -> {
        Intent i = new Intent(MainActivity.this,UserActivity.class);
        i.putExtra("psalm",psalm);
        startActivity(i);
    });
 }

если пишу: i.putExtra("psalm",psalm); ничего не передает в "UserActivity"(String psalm = intent.getStringExtra("psalm"); ). Если пишу i.putExtra("psalm",psalm[position]) - выводит, но только по номеру строки, а не то, что нажал. Может я вообще не там копаю?

→ Ссылка