web-dev-qa-db-fra.com

Android liste de recherche lors de la frappe

Comment puis-je créer une barre de recherche où, pendant que je tape, les résultats sont affichés dans le ListView dans lequel je recherche?

Par exemple, j'ai une vue de liste avec 20 chaînes. J'appuie sur la touche de recherche et apparaît la barre. Je veux que lorsque je tape 3 mots ou plus, la recherche commence à s'exécuter en affichant les résultats dans la liste (en tant que filtre: affiche uniquement les chaînes de la liste correspondant à ce que je tape)

23
xger86x

Vous ne pouvez pas faire cela avec la barre de recherche. Mais la vue de liste a la possibilité de filtre sur la touche enfoncée , comme cela se fait dans les contacts. L'utilisateur commence simplement à taper et la liste est ensuite filtrée. Le filtrage n'est pas vraiment comme la recherche. Si votre liste contient le mot foo quelque part et que vous tapez oo foo sera filtré, mais si vous tapez fo, il restera même si l'élément de la liste est la barre d'appel foo.

Vous devez simplement l'activer:

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

Je ne sais pas comment cela se fait si vous n'avez pas de clavier matériel. J'utilise le droïde et je commence à taper la liste à filtrer et à n'afficher que les résultats correspondants.

13
Janusz

Je pense que c'est ce que vous recherchez:

http://www.Java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

Demandez à votre activité d'implémenter SearchView.OnQueryTextListener

et ajoutez les méthodes suivantes:

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;
}
20
edst

J'ai utilisé un EditText pour faire le travail.

J'ai d'abord créé deux copies du tableau pour contenir la liste des données à rechercher:

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

Une fois que j'ai mes données de liste quelque part, je les copie:

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

et utilisez un SimpleAdapter pour afficher la version d'affichage (copiée) de mes données:

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);

J'ai ensuite ajouté un TextWatcher au EditText qui répond à un événement afterTextChanged en effaçant la version d'affichage de la liste, puis en rajoutant uniquement les éléments de l'autre liste qui se rencontrent les critères de recherche (dans ce cas le champ "reg" contient la chaîne de recherche). Une fois que la liste d'affichage est remplie avec la liste filtrée, j'appelle simplement notifyDataSetChanged sur le SimpleAdapter de la liste.

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 ...
});

J'espère que cela sera utile à quelqu'un.

10
Gareth

Utilisez le code suivant pour implémenter la recherche et la liste de filtres dans 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);
    }

}

Adaptateur de valeur personnalisé: 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();


        }

    }

}

activity_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>

J'espère que ce code sera utile pour implémenter une recherche personnalisée et filtrer la liste des vues

5
Mahesh

La meilleure façon consiste à utiliser la barre de recherche intégrée ou SearchManager en remplaçant onSearchRequested dans une activité consultable. Vous pouvez définir une source de données sur laquelle effectuer la recherche pour obtenir la liste déroulante automatique des résultats ou vous pouvez simplement saisir l'entrée de l'utilisateur et effectuer une recherche. Voici un bon aperçu de SearchManager est un Plus il y a une démo de travail dans le projet API Demos com.example.Android.apis.app.SearchQueryResult

@Override
public boolean onSearchRequested() {
1
Patrick Kafka