Pergunta

Como posso construir uma barra de pesquisa onde enquanto estou digitando os resultados são mostrados no ListView em que estou pesquisando?

Por exemplo, tenho uma visualização de lista com 20 strings. Eu pressiono a tecla de pesquisa e aparece a barra. Eu quero quando digito 3 palavras ou mais a pesquisa começa a ser executada mostrando os resultados na visualização da lista (como um filtro: mostra apenas as strings na lista que correspondem ao que eu digito)

Foi útil?

Solução

Você não pode fazer isso com a barra de pesquisa. Mas o ListView tem a possibilidade de filtro na tecla pressionada, como é feito nos contatos. O usuário simplesmente começa a digitar e a lista é filtrada então. Filtrar não é realmente como pesquisar. Se você listar contiver a palavra foo em algum lugar e você digita o Oo Foo será filtrado, mas se você digitar, ela ficará mesmo se o item da lista for uma barra de chamadas Foo.

Você simplesmente precisa ativá -lo:

ListView lv = getListView();
lv.setTextFilterEnabled(true);

Não sei como isso é feito se você não tiver um teclado de hardware. Estou usando o droid e começando a digitar inicia a lista para filtrar e mostrar apenas resultados correspondentes.

Outras dicas

Eu acredito que é isso que você está procurando:

http://www.java2s.com/code/android/2d-graphics/showsalistthatCanbefilteredinplacewithaseearchViewinNoniconifiedMode.htm

Peça à sua atividade implementar pesquisar a pesquisa.onQueryTextListener

e adicione os seguintes métodos:

public boolean onQueryTextChange(String newText) {
    if (TextUtils.isEmpty(newText)) {
        mListView.clearTextFilter();
    } else {
        mListView.setFilterText(newText.toString());
    }
    return true;
}

public boolean onQueryTextSubmit(String query) {
    return false;
}

Eu usei um EditText Para fazer o trabalho.

Primeiro, criei duas cópias da matriz para manter a lista de dados para pesquisar:

List<Map<String,String>> vehicleinfo;
List<Map<String,String>> vehicleinfodisplay;

Depois de receber os dados da minha lista de algum lugar, copio:

for(Map<String,String>map : vehicleinfo)
{
    vehicleinfodisplay.add(map);
}

e use um SimpleAdapter Para exibir a versão de exibição (copiada) dos meus dados:

String[] from={"vehicle","dateon","dateoff","reg"};
int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg};
listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to);
vehiclelist.setAdapter(listadapter);

Então eu adicionei um TextWatcher para o EditText que responde a um afterTextChanged Evento limpando a versão de exibição da lista e adicionando apenas os itens da outra lista que atendem aos critérios de pesquisa (neste caso, o campo "Reg" contém a sequência de pesquisa). Depois que a lista de exibição é preenchida com a lista filtrada, eu apenas ligo notifyDataSetChanged na lista SimpleAdapter.

searchbox.addTextChangedListener(new TextWatcher()
{
    @Override
    public void afterTextChanged(Editable s)
    {
        vehicleinfodisplay.clear();
        String search=s.toString();
        for(Map<String,String>map : vehicleinfo)
        {
            if(map.get("reg").toLowerCase().contains(search.toLowerCase()))
                vehicleinfodisplay.add(map);
            listadapter.notifyDataSetChanged();
        }
    };
    ... other overridden methods can go here ...
});

Espero que isto seja útil para alguém.

Use o código a seguir para implementar a lista de pesquisa e filtro no Android:

SearchAndFilterList.java

public class SearchAndFilterList extends Activity {

    private ListView mSearchNFilterLv;

    private EditText mSearchEdt;

    private ArrayList<String> mStringList;

    private ValueAdapter valueAdapter;

    private TextWatcher mSearchTw;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_search_and_filter_list);

        initUI();

        initData();

        valueAdapter=new ValueAdapter(mStringList,this);

        mSearchNFilterLv.setAdapter(valueAdapter);

        mSearchEdt.addTextChangedListener(mSearchTw);


    }
    private void initData() {

        mStringList=new ArrayList<String>();

        mStringList.add("one");

        mStringList.add("two");

        mStringList.add("three");

        mStringList.add("four");

        mStringList.add("five");

        mStringList.add("six");

        mStringList.add("seven");

        mStringList.add("eight");

        mStringList.add("nine");

        mStringList.add("ten");

        mStringList.add("eleven");

        mStringList.add("twelve");

        mStringList.add("thirteen");

        mStringList.add("fourteen");

        mSearchTw=new TextWatcher() {

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

                valueAdapter.getFilter().filter(s);
            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        };

    }

    private void initUI() {

        mSearchNFilterLv=(ListView) findViewById(R.id.list_view);

        mSearchEdt=(EditText) findViewById(R.id.txt_search);
    }

}

Adaptador de valor personalizado:ValueAdapter.java

public class ValueAdapter extends BaseAdapter implements Filterable{

    private ArrayList<String> mStringList;

    private ArrayList<String> mStringFilterList;

    private LayoutInflater mInflater;

    private ValueFilter valueFilter;

    public ValueAdapter(ArrayList<String> mStringList,Context context) {

        this.mStringList=mStringList;

        this.mStringFilterList=mStringList;

        mInflater=LayoutInflater.from(context);

        getFilter();
    }

    //How many items are in the data set represented by this Adapter.
    @Override
    public int getCount() {

        return mStringList.size();
    }

    //Get the data item associated with the specified position in the data set.
    @Override
    public Object getItem(int position) {

        return mStringList.get(position);
    }

    //Get the row id associated with the specified position in the list.
    @Override
    public long getItemId(int position) {

        return position;
    }

    //Get a View that displays the data at the specified position in the data set.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Holder viewHolder;

        if(convertView==null) {

            viewHolder=new Holder();

            convertView=mInflater.inflate(R.layout.list_item,null);

            viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem);

            convertView.setTag(viewHolder);

        }else{

            viewHolder=(Holder)convertView.getTag();
        }

            viewHolder.nameTv.setText(mStringList.get(position).toString());

            return convertView;
    }

    private class  Holder{

        TextView nameTv;
    }

    //Returns a filter that can be used to constrain data with a filtering pattern.
    @Override
    public Filter getFilter() {

        if(valueFilter==null) {

            valueFilter=new ValueFilter();
        }

        return valueFilter;
    }


    private class ValueFilter extends Filter {


        //Invoked in a worker thread to filter the data according to the constraint.
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results=new FilterResults();

            if(constraint!=null && constraint.length()>0){

                ArrayList<String> filterList=new ArrayList<String>();

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

                    if(mStringFilterList.get(i).contains(constraint)) {

                        filterList.add(mStringFilterList.get(i));

                    }
                }


                results.count=filterList.size();

                results.values=filterList;

            }else{

                results.count=mStringFilterList.size();

                results.values=mStringFilterList;

            }

            return results;
        }


        //Invoked in the UI thread to publish the filtering results in the user interface.
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            mStringList=(ArrayList<String>) results.values;

            notifyDataSetChanged();


        }

    }

}

Atividade_search_and_filter_list.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txt_search"
        tools:context=".SearchAndFilterList"
        android:hint="Enter text to search" />
    <ListView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/list_view"
        android:layout_below="@+id/txt_search"></ListView>

</RelativeLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txt_listitem"/>

</RelativeLayout>

Androidmanifext.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.searchandfilterlistview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SearchAndFilterList"
            android:label="@string/title_activity_search_and_filter_list" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Espero que este código seja útil para implementar a pesquisa personalizada e o filtro ListView

A melhor maneira é usar a barra de pesquisa ou o SearchManager incorporado, substituindo o OneSearch -Rested em uma atividade pesquisável. Você pode definir um DataSource para pesquisar para obter a queda automática de resultados ou pode apenas receber a entrada do usuário e pesquisar depois. Aqui está uma boa visão geral de SearchManager é uma vantagem que há uma demonstração de trabalho no projeto de demos da API com.example.android.apis.app.searchQueryResult

@Override
public boolean onSearchRequested() {
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top