Android SearchView Beispiel-Tutorial unter Verwendung von DataBinding

Heute werden wir uns das Android SearchView-Widget ansehen und eine Anwendung entwickeln, die eine ListView nach dem eingegebenen Text filtert. Wir werden DataBinding verwenden, um die Layouts in den Aktivitäten und Adaptern zu verbinden. Wenn Sie noch nichts über DataBinding gelesen haben, lesen Sie zuerst hier das Tutorial für ein besseres Verständnis.

Android SearchView

Android ermöglicht es uns, die Suchfunktion in unserer App zu verwenden, indem wir das SearchView-Widget entweder in der ToolBar/ActionBar anzeigen oder es in ein Layout einfügen. Das SearchView-Widget ist ab Android 3.0 verfügbar. Das SearchView wird im XML-Layout wie folgt definiert.

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

Es gibt viele Möglichkeiten der Suche in Android, wie z.B. die Sprachsuche, Vorschläge usw. In diesem Tutorial verwenden wir die Schnittstellen SearchView.OnQueryTextListener und Filterable. Die Filterable-Schnittstelle filtert den abgefragten Text über eine ListView und zeigt die resultierenden ListView-Zeilen an. Die Schnittstelle OnQueryTextListener kann zwei Ereignisse erkennen.

  1. onQueryTextChange wird aufgerufen, wenn der Benutzer jeden Buchstaben im Textfeld eingibt
  2. onQueryTextSubmit wird ausgelöst, wenn die Suche gedrückt wird

Android SearchView Beispiel

Das folgende Bild zeigt das endgültige Android SearchView Beispielprojekt. Das Projekt besteht aus einer Aktivität und einem Adapter für die ListView.

Android SearchView Beispielcode

Das activity_main.xml sieht folgendermaßen aus. Es besteht aus einer ListView mit einem SearchView oben. 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>

Das MainActivity.java sieht folgendermaßen aus.

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

Im obigen Code übergeben wir eine ArrayList von Monaten an den List Adapter. Wir rufen die filter-Methode auf, die in der Adapterklasse definiert ist, jedes Mal, wenn sich der Suchabfrage-Text ändert. Die ListAdapter.java-Klasse sieht so aus.

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

    }

}

Wie Sie im obigen Code sehen können, führen wir die Filterung mithilfe einer inneren Klasse ValueFilter durch, die die Filterklasse erweitert. Sie filtert die Liste, indem sie überprüft, ob der Suchabfrage-Text mit den in der ArrayList angegebenen Zeichenfolgen übereinstimmt. Das XML-Layout für die ListView-Zeile sieht folgendermaßen aus. 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>

Die Ausgabe der Android-Suchansichtsanwendung in Aktion wird unten angegeben. Die oben gezeigte SearchView erfordert, dass wir das Suchsymbol drücken, um das Textfeld zu aktivieren. Außerdem enthält es keinen Hinweis/Platzhaltertext. Fügen Sie den folgenden Code in die MainActivity ein, um die SearchView standardmäßig zu aktivieren und einen Hinweis anzuzeigen.

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

Die SearchView nach Anpassung sieht so aus. Damit endet das Android SearchView Tutorial. Wir werden uns später in einem weiteren Tutorial mit den erweiterten Funktionen der SearchView befassen. Sie können das Android SearchView-Projekt über den unten stehenden Link herunterladen.

Laden Sie das Beispielprojekt für Android SearchView herunter

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