今天学习SearchView控件,开始呢想翻译官网上的文章,但是后来发现那里面的东西太多,对我们学习SearchView控件来说有点繁琐。最终还是决定按照自己的步骤来写......

说了些废话,下面先看看效果图:

android studio搜索框回退按钮 android studio searchview_控件

主界面中包含一个SearchView控件,输入搜索内容后,点击键盘的“go”提交搜索内容,进入查询,然后用一个List显示出查询到的结果。接下来一步一步实现该功能:

1、创建Searchable配置文件

首先,在res/xml目录下添加配置文件searchable.xml——该配置文件确定了使用searchView还是searchDialog和定义了一些功能的行为,如suggestions、voice search 。

注:系统用该文件去初始化SearchInfo对象,但是用户不能在运行时创建该对象。

该searchable.xml配置文件必须以<searchable>为根节点并且指定一个或多个属性,本文中searchable.xml的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/app_name"
    android:label="@string/app_name" >

</searchable>

android:lable属性是唯一一个必须给定的属性。它指向一个字符串,该字符串应该用应用的名称。该label在 可以使用 Quick Search Box 的 search suggestions之前是不可见的。

虽然不是必须的,但是还是强烈建议添加android:hint属性,它在用户未输入任何内容时显示一个字符串——该字符串提给用户可以搜索数据的线索。


2、创建searchable activity —— WidgetSearchViewActivity

searchable activity 也是 application 中的一个activity , 它用于执行搜索和显示搜索结果。

当用户从SearchView中执行一个搜索操作,系统将会启动 searchable activity 并且通过intent传递搜索条件——该intent的action为ACTION_SEARCH,查询条件字符串在key为QUERY的附件中,然后执行搜索和显示结果。WidgetSearchViewActivity内容如下:

package com.xy.zt.selfdefinewieget;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class WidgetSearchViewActivity extends Activity {
    static final String[] DATA_COLLECTION = {
            "abc", "good", "baidu", "ni ku", "mitu", "爱不解释", "张婷是肯德基快睡觉都is开老实交代覅",
            "混蛋卡死了飞机是了快递费", "sldf", "android", "apk"
    };

    private SearchView mSv;
    private SearchManager mSearMan;
    private SearchViewAdapter mAdapter;
    private ListView mSearchList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.widget_search_view_laout);
        init();
    }

    private void init() {
        mSearMan = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        mSv = (SearchView) findViewById(R.id.show_search_view);
        mSearchList = (ListView) findViewById(R.id.search_list_view);
        mSv.setSearchableInfo(mSearMan.getSearchableInfo(getComponentName()));
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.getAction().equals(Intent.ACTION_SEARCH)) {
            // the string used to query
            String query = intent.getStringExtra(SearchManager.QUERY);
            doMySearch(query);
        }
    }

    private void doMySearch(String str) {
        ArrayList<String> data = new ArrayList<String>();
        for (int i = 0; i < DATA_COLLECTION.length; i++) {
            if (DATA_COLLECTION[i].contains(str)) {
                data.add(DATA_COLLECTION[i]);
            }
        }
        if (mAdapter == null) {
            mAdapter = new SearchViewAdapter(this, data);
            mSearchList.setAdapter(mAdapter);
        } else {
            mAdapter.mData = data;
            mAdapter.notifyDataSetChanged();
        }
    }

    private static class SearchViewAdapter extends BaseAdapter {

        public List<String> mData;
        LayoutInflater mInflater;

        public SearchViewAdapter(Context context, List<String> data) {
            if (context == null || data == null)
                throw new IllegalArgumentException("argument data or context is null .");
            mData = data;
            mInflater = LayoutInflater.from(context);
        }

        public int getCount() {
            return mData.size();
        }

        public Object getItem(int pos) {
            return mData.get(pos);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = mInflater.inflate(R.layout.search_view_data_item, null);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.mDataItem = (TextView) convertView.findViewById(R.id.searched_data_item);
            holder.mDataItem.setText((String) getItem(position));
            return convertView;
        }

    }

    private static class ViewHolder {
        public TextView mDataItem;
    }
}



static final String[] DATA_COLLECTION = {
            "abc", "good", "baidu", "ni ku", "mitu", "爱不解释", "张婷是肯德基快睡觉都is开老实交代覅",
            "混蛋卡死了飞机是了快递费", "sldf", "android", "apk"
    };

是搜索的数据集合,当提交搜索后执行下面代码


@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.getAction().equals(Intent.ACTION_SEARCH)) {
            // the string used to query
            String query = intent.getStringExtra(SearchManager.QUERY);
            doMySearch(query);
        }
    }



3、申明searchable activity

如果没有改searchable activity 则创建它,创建该activity需要注意两点:

3.1、申明该activity接受ACTION_SEARCH的intent

3.2、在meta-data元素中指定searchable配置文件

widgetSearchViewActivity的申明如下:

<activity
            android:name="WidgetSearchViewActivity"
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

meta_data必须包含两个属性:

android:name=“android.app.searchable” :该属性的值必须是android.app.searchable.

android:resource="@xml/..." : 该属性指向searchable 配置文件。
4、使用到的布局文件

4.1 widget_search_view_laout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <SearchView
        android:id="@+id/show_search_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="15dp"
        android:iconifiedByDefault="false"
        android:imeOptions="actionSearch" >
    </SearchView>

    <ListView
        android:id="@+id/search_list_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="15dp" >
    </ListView>

</LinearLayout>

4.2search_view_data_item.xml (ListView中使用到的每个item的布局文件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/widget_button_drawable"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/searched_data_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/auto_complete_font_color" />

</LinearLayout>

代码中使用到的背景可参见

一步一步学android控件(之三) —— Button



5、在ViewData.java中添加如下内容(此部分内容可选,若有不清楚的地方参见

一步一步学android控件(之一) —— 开始篇

public static final int SEARCH_VIEW_ID = VIEW_FLIPPER_ID + 1;
    public static final String SEARCH_VIEW_NAME = "SearchView";
private static final ViewData mSearchView = new ViewData(SEARCH_VIEW_NAME,
            SEARCH_VIEW_ID);
View_Datas.add(mSearchView);

在WidgetsAdapter的handleItemClicked方法中添加如下内容

case ViewData.SEARCH_VIEW_ID:
                intent.setClass(mContext, WidgetSearchViewActivity.class);
                mContext.startActivity(intent);
                break;

以上就是SearchView的全部内容。到此为止学习了android中大多数控件,应该够日常开发的了

... ...若后面发现还有该写而没有写到的控件再添加了。下一篇,该系列的尾章,将会上传所有的代码,你会发现android控件的学习是  So Easy !^_^