Поиск по этому блогу

четверг, 5 сентября 2013 г.

Живой поиск в ListView через EditText

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

Для начала создайте новый проект в Eclipse если конечно он у вас установлен, если не установлен то прошу в этот тред, далее если у Вас все хорошо и проект вы создали, открываем файл activity_main.xml и удаляем все что там и копируем вот этот текст:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
     
    <!-- Editext для поиска -->
    <EditText android:id="@+id/inputSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Search products.."
        android:inputType="textVisiblePassword"/>
  
    <!-- List View -->
    <ListView
        android:id="@+id/list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
  
</LinearLayout>


Это задаст нашему окну красивый вид с списком и полем для ввода вверху, а еще нам нужно создать доп. файл с одним TextView в который будем выводить наш список данных. Его мы назовем list_item.xml и вот что он будет в себе содержать:

list_item.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" >
     
    <!-- Товары которые будут в списке-->
    <TextView android:id="@+id/product_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dip"
        android:textSize="16dip"
        android:textStyle="bold"/>    
 
</LinearLayout>


Дальше нам нужно создать класс который будет выводить все нужные для нас данные, в нем у нас будет вызываться адаптер который будет выводить из массива данные.

Открываем наш класс MainActivity.java и вставляем следующий код:

MainActivity.java
package com.example.liveedittext;
 
import java.util.ArrayList;
import java.util.HashMap;
 
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
 
public class MainActivity extends Activity {
     
    // List view
    private ListView lv;
    // Listview Adapter
    ArrayAdapter<String> adapter;
    // EditText в котором будем искать
    EditText inputSearch;
    // ArrayList для Listview
    ArrayList<HashMap<String, String>> productList;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        // Вот что мы будем выводить в ListView
        String products[] = {"Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "HTC Sensation XE",
                                "iPhone 4S", "Samsung Galaxy Note 800",
                                "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"};
         
        lv = (ListView) findViewById(R.id.list_view);
        inputSearch = (EditText) findViewById(R.id.inputSearch);
         
        // Добавляем данные для ListView
        adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products);
        lv.setAdapter(adapter);       
    }
}


Здесь все просто, создали адаптер, создали ListView, создали массив с данными которые нужно вывести, дальше определили все параметры и вывели текст в адаптере на ListView, если не помните как работает это то советую прочитать мою первую статью про ListView, там все очень щепетильно описано что куда и как работает.

image
Вот так будет выглядеть программа на данном этапе.


Теперь нам нужно сделать так что бы при введении текста в программе что-то менялось, а что же должно меняться? А должны отсеиваться не подходящие по слову или букве слова. Как это сделать? Для этого нам нужно использовать встроенную функцию Android'a которая называется addTextChangedListener(), она считывает посимвольно каждый раз когда вы вводите текст в поле ввода, т.е. она обновляется каждый раз как вы кликните по какой либо букве на клавиатуре.

Что же, теперь давайте добавим ее в наш код, для этого делаем несколько отступов от последней строчки в onCreate() от этого места lv.setAdapter(adapter); и вставляем следующий код:

MainActivity.java
inputSearch.addTextChangedListener(new TextWatcher() {
     
    @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
        // Когда, юзер изменяет текст он работает
        MainActivity.this.adapter.getFilter().filter(cs);   
    }
     
    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
            int arg3) {
        // TODO Auto-generated method stub
         
    }
     
    @Override
    public void afterTextChanged(Editable arg0) {
        // TODO Auto-generated method stub                          
    }
});


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

image
То что будет показывать программа при вводе буквы «S».


Собственно вот и все, это не сильно сложный функционал, но смотрится довольно красиво, давно хотел что-то похожее научиться делать, собственно вот и дошли руки. Спасибо за внимание, будут вопросы пишите, постараюсь ответить в любом состоянии. (:

Скачать исходники GitHub | DropBox