Android SearchView und DataBinding: Eine Schritt-für-Schritt-Anleitung

In diesem Blogbeitrag zeigen wir Ihnen, wie Sie eine Android-Anwendung mit einer SearchView entwickeln, die es ermöglicht, eine ListView nach bestimmten Begriffen zu durchsuchen. Wir verwenden dabei DataBinding, um Layouts in Activities und Adaptern zu verbinden. DataBinding ist eine nützliche Technik, um den Code übersichtlicher und effizienter zu gestalten.

Was ist die Android SearchView?

Die Android SearchView ist ein Widget, das Suchfunktionen innerhalb Ihrer App bereitstellt. Sie kann sowohl in der ToolBar/ActionBar als auch innerhalb eines Layouts eingesetzt werden. Seit Android 3.0 ist sie verfügbar und bietet viele Funktionen wie z. B. die Textsuche, Vorschläge und sogar Sprachsuche.

Eine einfache Implementierung in einem XML-Layout sieht so aus:

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

In diesem Beispiel verwenden wir das Interface SearchView.OnQueryTextListener sowie die Schnittstelle Filterable, um die Suchanfragen zu bearbeiten. OnQueryTextListener ermöglicht uns, zwei wesentliche Ereignisse abzufangen:

  1. onQueryTextChange: Wird aufgerufen, wenn der Benutzer Zeichen in das Suchfeld eingibt.
  2. onQueryTextSubmit: Wird ausgelöst, wenn der Benutzer die Suchanfrage abschickt.

Implementierung eines Beispiels für die Android SearchView

Im folgenden Beispiel erstellen wir eine Activity, die eine SearchView und eine ListView enthält. Die ListView wird mit einer Liste von Monatsnamen gefüllt, die wir durch die Suchanfrage filtern.

activity_main.xml

Das Hauptlayout besteht aus einer SearchView und einer ListView:

<layout xmlns:android="http://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_below="@+id/search" />

    </RelativeLayout>

</layout>

MainActivity.java

In der MainActivity nutzen wir DataBinding, um die View-Komponenten mit dem Code zu verbinden. Wir erstellen außerdem eine ArrayList mit Monatsnamen und setzen einen Adapter, um diese Liste in der ListView anzuzeigen. Die Suchanfragen werden gefiltert, indem der Adapter die Filter-Methode aufruft, sobald sich der Text in der SearchView ändert.

package com.example.searchviewexample;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import com.example.searchviewexample.databinding.ActivityMainBinding;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;
    ListAdapter adapter;
    List<String> monthList = new ArrayList<>();

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

        // Füllen der Monatsnamen
        monthList.add("Januar");
        monthList.add("Februar");
        monthList.add("März");
        monthList.add("April");
        monthList.add("Mai");
        monthList.add("Juni");
        monthList.add("Juli");
        monthList.add("August");
        monthList.add("September");
        monthList.add("Oktober");
        monthList.add("November");
        monthList.add("Dezember");

        // Adapter für die Liste setzen
        adapter = new ListAdapter(monthList);
        binding.listView.setAdapter(adapter);

        // SearchView konfigurieren
        binding.search.setActivated(true);
        binding.search.setQueryHint("Suchbegriff eingeben");
        binding.search.onActionViewExpanded();
        binding.search.setIconified(false);
        binding.search.clearFocus();

        // Suchfunktion hinzufügen
        binding.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;
            }
        });
    }
}

ListAdapter.java

Der Adapter dient dazu, die Daten an die ListView zu binden. Hier verwenden wir die Schnittstelle Filterable, um die Liste basierend auf der Suchanfrage zu filtern.

package com.example.searchviewexample;

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.example.searchviewexample.databinding.RowItemBinding;
import java.util.ArrayList;
import java.util.List;

public class ListAdapter extends BaseAdapter implements Filterable {

    List<String> dataList;
    List<String> filteredList;
    ValueFilter valueFilter;
    private LayoutInflater inflater;

    public ListAdapter(List<String> list) {
        dataList = list;
        filteredList = list;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null) {
            inflater = (LayoutInflater) parent.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
        RowItemBinding rowBinding = DataBindingUtil.inflate(inflater, R.layout.row_item, parent, false);
        rowBinding.stringName.setText(dataList.get(position));
        return rowBinding.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 < filteredList.size(); i++) {
                    if (filteredList.get(i).toUpperCase().contains(constraint.toString().toUpperCase())) {
                        filterList.add(filteredList.get(i));
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                results.count = filteredList.size();
                results.values = filteredList;
            }
            return results;
        }

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

Fazit

In diesem Beispiel haben wir eine einfache Android-Anwendung erstellt, die eine Liste von Monatsnamen durchsuchbar macht. Durch die Verwendung von DataBinding und der Schnittstelle Filterable bleibt der Code sauber und übersichtlich.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: