声明:其实官方已经有了通过menu区的实现方法,参见这里。
需要说明的是,若你使用的是support.v7,一定要如下配置menu资源(解决见这里),否则拿不到menuItem.getActionView()会返回null,下面的menu配置请注意两个app
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/action_search" android:title="@string/search_hint" android:icon="@android:drawable/ic_menu_search" app:showAsAction="always|collapseActionView" app:actionViewClass="android.support.v7.widget.SearchView" /> <item android:id="@+id/action_settings" android:title="@string/action_settings" android:orderInCategory="100" app:showAsAction="never" /> </menu>
下面这个转载的方法挺土的,不建议使用。
转载自:《Android SearchView介绍及搜索提示实现》
本文主要介绍SearchView的使用、即时搜索提示功能的实现,以及一些设置。
具体代码可见SearchViewDemo@Github,可实现效果如下:
示例APK可从这些地址下载:Google Play, 360手机助手, 百度手机助手, 小米应用商店, 豌豆荚
1、layout文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <SearchView android:id="@+id/search_view" android:layout_width="match_parent" android:layout_height="match_parent" android:iconifiedByDefault="true" android:inputType="textCapWords" android:imeOptions="actionSearch" android:queryHint="" /> </RelativeLayout>
xml中主要配置有四个属性,如下:
android:iconifiedByDefault表示搜索图标是否在输入框内。true效果更加
android:imeOptions设置IME options,即输入法的回车键的功能,可以是搜索、下一个、发送、完成等等。这里actionSearch表示搜索
android:inputType输入框文本类型,可控制输入法键盘样式,如numberPassword即为数字密码样式
android:queryHint输入框默认文本
2、 java部分代码
SearchView几个主要函数
- setOnCloseListener(SearchView.OnCloseListener listener)表示点击取消按钮listener,默认点击搜索输入框
- setOnQueryTextListener(SearchView.OnQueryTextListener listener)表示输入框文字listener,包括public boolean onQueryTextSubmit(String query)开始搜索listener,public boolean onQueryTextChange(String newText)输入框内容变化listener,两个函数,下面代码包含了如何利用延迟执行实现搜索提示
package cn.trinea.android.demo; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import android.app.ActionBar; import android.app.ActionBar.LayoutParams; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.SearchView; import android.widget.SearchView.OnCloseListener; import android.widget.Toast; public class SearchViewDemo extends Activity { private SearchView searchView; private Context context; private MyHandler handler; // schedule executor private ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(10); private String currentSearchTip; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search_view_demo); context = getApplicationContext(); handler = new MyHandler(); ActionBar actionBar = getActionBar(); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM); setTitle(" "); LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); View customActionBarView = inflater.inflate(R.layout.search_view_demo_title, null); searchView = (SearchView)customActionBarView.findViewById(R.id.search_view); searchView.setIconified(false); searchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { // to avoid click x button and the edittext hidden return true; } }); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { public boolean onQueryTextSubmit(String query) { Toast.makeText(context, "begin search", Toast.LENGTH_SHORT).show(); return true; } public boolean onQueryTextChange(String newText) { if (newText != null && newText.length() > 0) { currentSearchTip = newText; showSearchTip(newText); } return true; } }); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.RIGHT); actionBar.setCustomView(customActionBarView, params); // show keyboard getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } public void showSearchTip(String newText) { // excute after 500ms, and when excute, judge current search tip and newText schedule(new SearchTipThread(newText), 500); } class SearchTipThread implements Runnable { String newText; public SearchTipThread(String newText){ this.newText = newText; } public void run() { // keep only one thread to load current search tip, u can get data from network here if (newText != null && newText.equals(currentSearchTip)) { handler.sendMessage(handler.obtainMessage(1, newText + " search tip")); } } } public ScheduledFuture<?> schedule(Runnable command, long delayTimeMills) { return scheduledExecutor.schedule(command, delayTimeMills, TimeUnit.MILLISECONDS); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: { onBackPressed(); return true; } } return false; } private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Toast.makeText(context, (String)msg.obj, Toast.LENGTH_SHORT).show(); break; } } } }
上面代码在onQueryTextChange函数即输入框内容每次变化时将一个数据获取线程SearchTipThread放到ScheduledExecutorService中,500ms后执行,在线程执行时判断当前输入框内容和要搜索内容,若相等则继续执行,否则直接返回,避免不必要的数据获取和多个搜索提示同时出现。
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
searchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { return true; } });
searchView.onActionViewExpanded();表示在内容为空时不显示取消的x按钮,内容不为空时显示.
searchView.setSubmitButtonEnabled(true);编辑框后显示search按钮,个人建议用android:imeOptions=”actionSearch”代替。
隐藏输入法键盘
InputMethodManager inputMethodManager; inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); private void hideSoftInput() { if (inputMethodManager != null) { View v = SearchActivity.this.getCurrentFocus(); if (v == null) { return; } inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); searchView.clearFocus(); } }