Упатство за пример на Android SearchView со користење на DataBinding


Денес ќе го разгледаме додатокот за Android SearchView и ќе развиеме апликација која филтрира ListView според прашаниот текст. Ќе користиме DataBinding за да ги поврземе распоредите во Активностите и адаптерите. Ако не сте прочитале за DataBinding, прво упатете го ова упатство за подобро разбирање.

Андроид SearchView

Андроид ни овозможува да ја користиме функционалноста за пребарување во нашата апликација со прикажување на виџетот SearchView или во ToolBar/ActionBar или вметнувајќи го во распоред. Виџетот за Android SearchView е достапен од Android 3.0 наваму. SearchView е дефиниран во распоредот на XML како што е прикажано подолу.

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

Има многу форми за пребарување во Андроид, како што се гласовно пребарување, предлози итн. Во ова упатство ќе користиме интерфејси SearchView.OnQueryTextListener и Filterable. Интерфејсот за филтрирање го филтрира прашаниот текст преку ListView и ги прикажува добиените редови ListView. Интерфејсот OnQueryTextListener може да открие два настани.

  1. onQueryTextChange се повикува кога корисникот ќе го напише секој знак во полето за текст
  2. onQueryTextSubmit се активира кога ќе се притисне пребарувањето

Андроид SearchView Пример

Андроид SearchView Пример код

Activity_main.xml е дадена подолу. Се состои од ListView со SearchView на врвот. 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>

MainActivity.java е даден подолу.

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

Во горната шифра, пренесуваме ArrayList of Months на адаптерот за листа. Го повикуваме методот на филтрирање што е дефиниран во класата на адаптер секогаш кога се менува текстот на барањето за пребарување. Класата ListAdapter.java изгледа вака.

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

    }

}

Како што можете да видите во горниот код, ние вршиме филтрирање користејќи внатрешна класа ValueFilter која ја проширува класата Filter. Ја филтрира листата со проверка дали текстот на барањето за пребарување се совпаѓа со низите дадени во ArrayList. Распоредот на XML за редот ListView е даден подолу. 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>
activityMainBinding.search.setActivated(true);
        activityMainBinding.search.setQueryHint("Type your keyword here");
        activityMainBinding.search.onActionViewExpanded();
        activityMainBinding.search.setIconified(false);
        activityMainBinding.search.clearFocus();

Преземете го Android SearchView Example Project