[转]Android SearchView介绍及搜索提示实现

声明:其实官方已经有了通过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();
	}
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *