Today we will look into Android SearchView widget and develop an application that filters a ListView by the queried text. We’ll be using DataBinding to hook up the layouts in the Activities and Adapters. If you haven’t read about DataBinding refer this tutorial first for a better understanding.
今天,我们将研究Android SearchView小部件,并开发一个应用程序,该应用程序可通过查询的文本过滤ListView。 我们将使用DataBinding来连接“活动”和“适配器”中的布局。 如果您还没有阅读有关DataBinding的信息,请先参考本教程以获取更好的理解。
Android SearchView (Android SearchView)
Android allows us to use the search functionality in our app by displaying the SearchView widget either in the ToolBar/ActionBar or inserting it into a layout. Android SearchView widget is available from Android 3.0 onwards.
Android通过在ToolBar / ActionBar中显示SearchView小部件或将其插入到布局中来允许我们在应用中使用搜索功能。 从Android 3.0开始可以使用Android SearchView小部件。
The SearchView is defined in the XML layout as shown below.
SearchView在XML布局中定义,如下所示。
<android.support.v7.widget.SearchView
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
There are many forms for searching in Android such as voice search, suggestions etc. In this tutorial we’ll use SearchView.OnQueryTextListener
and Filterable
interfaces.
Android中有多种搜索形式,例如语音搜索,建议等。在本教程中,我们将使用SearchView.OnQueryTextListener
和Filterable
接口。
The Filterable interface filters the queried text over a ListView and displays the resulted ListView rows.
Filterable接口过滤ListView上查询的文本,并显示结果ListView行。
OnQueryTextListener
interface can detect two events.
OnQueryTextListener
接口可以检测两个事件。
onQueryTextChange
is called when the user types each character in the text field 当用户在文本字段中键入每个字符时,将调用onQueryTextChange
onQueryTextSubmit
is triggered when the search is pressed 按下搜索时会触发onQueryTextSubmit
Android SearchView示例 (Android SearchView Example)
Below image shows the final android SearchView example project.
下图显示了最终的Android SearchView示例项目。
The project consists of an Activity and an Adapter for the ListView.
该项目由一个Activity和一个用于ListView的适配器组成。
Android SearchView示例代码 (Android SearchView Example Code)
The activity_main.xml is given below. It consists of a ListView with a SearchView on top.
下面给出activity_main.xml。 它由一个ListView和一个顶部SearchView组成。
activity_main.xml
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>
The MainActivity.java is given below.
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;
}
});
}
}
In the above code, we are passing an ArrayList of Months to the List Adapter.
在上面的代码中,我们将一个月的ArrayList传递给列表适配器。
We’re invoking the filter method that’s defined in the adapter class every time the search query text changes.
每次搜索查询文本更改时,我们都会调用适配器类中定义的filter方法。
The ListAdapter.java class looks like this.
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();
}
}
}
As you can see in the above code we’re performing filtering using an inner class ValueFilter
that extends the Filter class. It filters the list by checking if the search query text matches the strings given in the ArrayList.
如您在上面的代码中看到的,我们正在使用扩展了Filter类的内部类ValueFilter
执行过滤。 它通过检查搜索查询文本是否与ArrayList中给定的字符串匹配来过滤列表。
The XML layout for the ListView row is given below.
下面给出了ListView行的XML布局。
row_item.xml
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>
The output of the android search view application in action is given below.
运行中的android search view应用程序的输出如下。
The SearchView shown above requires us to press the search icon to activate the text field. Also, it doesn’t contain any hint/placeholder text.
上面显示的SearchView要求我们按搜索图标以激活文本字段。 另外,它不包含任何提示/占位符文本。
Add the following code in the MainActivity to enable the SearchView by default and display a hint.
在MainActivity中添加以下代码以默认启用SearchView并显示提示。
activityMainBinding.search.setActivated(true);
activityMainBinding.search.setQueryHint("Type your keyword here");
activityMainBinding.search.onActionViewExpanded();
activityMainBinding.search.setIconified(false);
activityMainBinding.search.clearFocus();
The SearchView after customising as above looks like this.
This brings an end to android SearchView tutorial. We’ll dive into the advanced features of SearchView in a later tutorial. You can download the Android SearchView Project from the link given below.
这就结束了Android SearchView教程。 在后面的教程中,我们将深入探讨SearchView的高级功能。 您可以从下面提供的链接下载Android SearchView项目 。
翻译自: https://www.journaldev.com/12478/android-searchview-example-tutorial