Android Zoekweergave Voorbeeld Zelfstudie met Gebruik van DataBinding

Vandaag gaan we kijken naar de Android SearchView-widget en een toepassing ontwikkelen die een ListView filtert op basis van de ingevoerde tekst. We zullen DataBinding gebruiken om de lay-outs in de activiteiten en adapters met elkaar te verbinden. Als je nog niet hebt gelezen over DataBinding, raadpleeg dan eerst deze tutorial voor een beter begrip.

Android SearchView

Android stelt ons in staat om de zoekfunctionaliteit in onze app te gebruiken door de SearchView-widget weer te geven in de Toolbar/ActionBar of deze in een lay-out in te voegen. De Android SearchView-widget is beschikbaar vanaf Android 3.0. De SearchView wordt gedefinieerd in de XML-indeling zoals hieronder weergegeven.

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

Er zijn verschillende vormen van zoeken in Android, zoals spraakzoekopdrachten, suggesties, enz. In deze tutorial zullen we de SearchView.OnQueryTextListener– en Filterable-interfaces gebruiken. De Filterable-interface filtert de ingevoerde tekst over een ListView en toont de resulterende rijen in de ListView. De interface OnQueryTextListener kan twee gebeurtenissen detecteren.

  1. onQueryTextChange wordt aangeroepen wanneer de gebruiker elk karakter in het tekstveld typt
  2. onQueryTextSubmit wordt geactiveerd wanneer er op de zoekknop wordt gedrukt.

Voorbeeld van Android SearchView

Onderstaande afbeelding toont het uiteindelijke projectvoorbeeld van Android SearchView. Het project bestaat uit een Activity en een Adapter voor de ListView.

Voorbeeldcode van Android SearchView

De activity_main.xml wordt hieronder weergegeven. Het bevat een ListView met een SearchView bovenaan. 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>

De MainActivity.java wordt hieronder weergegeven.

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

In de bovenstaande code geven we een ArrayList van Maanden door aan de List Adapter. We roepen de filtermethode aan die elke keer verandert wanneer de zoekopdrachttekst wijzigt. De ListAdapter.java-klasse ziet er als volgt uit.

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

    }

}

Zoals je kunt zien in de bovenstaande code, voeren we filtering uit met behulp van een innerlijke klasse ValueFilter die de Filter-klasse uitbreidt. Het filtert de lijst door te controleren of de zoekopdrachttekst overeenkomt met de strings in de ArrayList. De XML-indeling voor de ListView-rij wordt hieronder gegeven. 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>

De uitvoer van de Android-zoekweergave in actie wordt hieronder gegeven. De hierboven weergegeven SearchView vereist dat we op het zoekpictogram drukken om het tekstveld te activeren. Bovendien bevat het geen hint/placeholder-tekst. Voeg de volgende code toe in de MainActivity om de SearchView standaard in te schakelen en een hint weer te geven.

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

De SearchView ziet er na deze aanpassing als volgt uit. Hiermee komt een einde aan de Android SearchView-tutorial. We zullen in een latere tutorial ingaan op de geavanceerde functies van de SearchView. Je kunt het Android SearchView Project downloaden vanaf de onderstaande link.

Download Android SearchView Example Project

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