Exemple de tutoriel Android SearchView utilisant DataBinding

Aujourd’hui, nous allons nous pencher sur le widget Android SearchView et développer une application qui filtre une ListView en fonction du texte saisi. Nous utiliserons DataBinding pour relier les mises en page dans les activités et les adaptateurs. Si vous n’avez pas encore lu à ce sujet, veuillez vous référer à ce tutoriel pour une meilleure compréhension.

Android SearchView

Android nous permet d’utiliser la fonctionnalité de recherche dans notre application en affichant le widget SearchView soit dans la barre d’outils/actionBar, soit en l’insérant dans une mise en page. Le widget SearchView d’Android est disponible à partir d’Android 3.0. Le SearchView est défini dans la mise en page XML comme indiqué ci-dessous.

<android.support.v7.widget.SearchView
        android:id="@+id/search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

Il existe de nombreuses formes de recherche sous Android, telles que la recherche vocale, les suggestions, etc. Dans ce tutoriel, nous utiliserons les interfaces SearchView.OnQueryTextListener et Filterable. L’interface Filterable filtre le texte recherché sur une ListView et affiche les lignes résultantes de la ListView. L’interface OnQueryTextListener peut détecter deux événements.

  1. onQueryTextChange est appelé lorsque l’utilisateur saisit chaque caractère dans le champ de texte
  2. onQueryTextSubmit est déclenché lorsque la recherche est appuyée

Exemple de SearchView Android

L’image ci-dessous montre le projet final de l’exemple de SearchView Android. Le projet se compose d’une activité et d’un adaptateur pour la ListView.

Code d’exemple de SearchView Android

Le fichier activity_main.xml est donné ci-dessous. Il se compose d’une ListView avec un SearchView en haut. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="https://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <android.support.v7.widget.SearchView
            android:id="@+id/search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true" />

        <ListView
            android:id="@+id/list_view"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/search" />

    </RelativeLayout>

</layout>

Le fichier MainActivity.java est donné ci-dessous.

package com.journaldev.searchview;

import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.SearchView;

import com.journaldev.searchview.databinding.ActivityMainBinding;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding activityMainBinding;
    ListAdapter adapter;

    List<String> arrayList= new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        arrayList.add("January");
        arrayList.add("February");
        arrayList.add("March");
        arrayList.add("April");
        arrayList.add("May");
        arrayList.add("June");
        arrayList.add("July");
        arrayList.add("August");
        arrayList.add("September");
        arrayList.add("October");
        arrayList.add("November");
        arrayList.add("December");

        adapter= new ListAdapter(arrayList);
        activityMainBinding.listView.setAdapter(adapter);

        activityMainBinding.search.setActivated(true);
        activityMainBinding.search.setQueryHint("Type your keyword here");
        activityMainBinding.search.onActionViewExpanded();
        activityMainBinding.search.setIconified(false);
        activityMainBinding.search.clearFocus();

        activityMainBinding.search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {

                adapter.getFilter().filter(newText);

                return false;
            }
        });
    }
}

Dans le code ci-dessus, nous passons une ArrayList de mois à l’adaptateur de liste. Nous invoquons la méthode de filtrage qui est définie dans la classe d’adaptateur à chaque fois que le texte de la requête de recherche change. La classe ListAdapter.java ressemble à ceci.

package com.journaldev.searchview;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import com.journaldev.searchview.databinding.RowItemBinding;
import java.util.ArrayList;
import java.util.List;

public class ListAdapter extends BaseAdapter implements Filterable {

    List<String> mData;
    List<String> mStringFilterList;
    ValueFilter valueFilter;
    private LayoutInflater inflater;

    public ListAdapter(List<String> cancel_type) {
        mData=cancel_type;
        mStringFilterList = cancel_type;
    }


    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public String getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, final ViewGroup parent) {

        if (inflater == null) {
            inflater = (LayoutInflater) parent.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
        RowItemBinding rowItemBinding = DataBindingUtil.inflate(inflater, R.layout.row_item, parent, false);
        rowItemBinding.stringName.setText(mData.get(position));


        return rowItemBinding.getRoot();
    }

    @Override
    public Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                List<String> filterList = new ArrayList<>();
                for (int i = 0; i < mStringFilterList.size(); i++) {
                    if ((mStringFilterList.get(i).toUpperCase()).contains(constraint.toString().toUpperCase())) {
                        filterList.add(mStringFilterList.get(i));
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                results.count = mStringFilterList.size();
                results.values = mStringFilterList;
            }
            return results;

        }

        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            mData = (List<String>) results.values;
            notifyDataSetChanged();
        }

    }

}

Comme vous pouvez le voir dans le code ci-dessus, nous effectuons le filtrage en utilisant une classe interne ValueFilter qui étend la classe Filter. Elle filtre la liste en vérifiant si le texte de la requête de recherche correspond aux chaînes données dans l’ArrayList. La mise en page XML pour la ligne de la ListView est donnée ci-dessous. row_item.xml

<layout xmlns:android="https://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/stringName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:padding="@dimen/activity_horizontal_margin"
            android:textAllCaps="false"
            android:textAppearance="?android:attr/textAppearanceMedium" />

    </RelativeLayout>

</layout>

La sortie de l’application de recherche Android SearchView en action est donnée ci-dessous. Le SearchView indiqué ci-dessus nécessite d’appuyer sur l’icône de recherche pour activer le champ de texte. De plus, il ne contient aucun texte d’indication/placeholder. Ajoutez le code suivant dans MainActivity pour activer le SearchView par défaut et afficher un texte d’indication.

activityMainBinding.search.setActivated(true);
        activityMainBinding.search.setQueryHint("Type your keyword here");
        activityMainBinding.search.onActionViewExpanded();
        activityMainBinding.search.setIconified(false);
        activityMainBinding.search.clearFocus();

Le SearchView, après personnalisation comme ci-dessus, ressemble à ceci. Cela met fin au tutoriel du SearchView Android. Nous aborderons les fonctionnalités avancées du SearchView dans un tutoriel ultérieur. Vous pouvez télécharger le projet Android SearchView en suivant le lien ci-dessous.

Télécharger le projet Android SearchView Example

Source:
https://www.digitalocean.com/community/tutorials/android-searchview-example-tutorial