Lista de pesquisa do Android ao digitar
-
24-09-2019 - |
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)
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:
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() {