ShelockActionBar的SearchView的学习

效果展示。search的suggest展示


点击键盘右下角的搜索 进入搜索结果界面展示:


首先我们定义了BaseActivity用于search 就是图1展示suggestion的

package com.mengqi.base.ui;

import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.widget.SearchView;
import com.actionbarsherlock.widget.SearchView.OnQueryTextListener;
import com.mengqi.base.R;

public class BaseActivity extends SherlockFragmentActivity implements OnQueryTextListener
{

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setContentView(R.layout.base_frame_left);
	}


//			如果要正常搜索必须返回false。如果返回true那么就不执行搜索。
//			看searchView的源码。只有这个监听器为空或者onQueryTextSubmit返回false才执行下面的
//			if (mOnQueryChangeListener == null
//	                || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
//	            if (mSearchable != null) {
//	                launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());  搜索跳转
//	                setImeVisibility(false);
//	            }
//	            dismissSuggestions();
//	        }
	@Override
    public boolean onQueryTextSubmit(String query)
    {
	    return false;
    }


//	这个返回什么都没有影响
	@Override
    public boolean onQueryTextChange(String newText)
    {
	    return false;
    }


			 
	@Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
		menu.add(0, R.id.menu_settings, 12, R.string.settings);
		
		getSupportMenuInflater().inflate(R.menu.search, menu);
		
		SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
//        这个SearchableInfo 是在AndroidManifest.xml进行初始化的 
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setQueryHint(getString(R.string.search_hint));
//        searchView.setOnQueryTextListener(this); 这个按照需求要不要处理。如果设置请注意onQueryTextSubmit返回false
	    return super.onCreateOptionsMenu(menu);
    }
}

menu的xml文件 menu_search

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:icon="@drawable/ic_action_search" 
        android:id="@id/menu_search"
        android:orderInCategory="10" 
        android:title="@string/search" 
        android:actionViewClass="com.actionbarsherlock.widget.SearchView"
        android:showAsAction="ifRoom|collapseActionView" />
</menu>

这个时候界面上ActionBar有了searchView的界面展示但是不能搜索,因为还没有配置SearchableInfo

所以res/xml/searchable.xml 新建

<?xml version="1.0" encoding="utf-8"?>
<searchable android:label="@string/app_name" android:hint="@string/search_hint" 
    android:searchSuggestAuthority="com.mengqi.base.provider" 
    android:searchSuggestPath="newsearch" android:searchSuggestSelection="like ?"
    android:searchSuggestIntentAction="com.mengqi.base.view" 
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
    android:searchSuggestThreshold="2" android:includeInGlobalSearch="true"
  xmlns:android="http://schemas.android.com/apk/res/android" />
这个设置要了解过contentProvider的人才会熟悉。如果不会先去补补吧,,,,,

contentprovider是通过uri进行数据查找的。

uri包含 scheme+authority+path  对应这个里面searchSuggest的相关配置。

如果searchSuggestSelection像上面设置。并且搜索‘187’ ,那么suggest发起的请求uri就是:(可以在自定义的contentProvider的query方法进行打印)

content://com.mengqi.base.provider/newsearch/search_suggest_query?limit=50 并且selectionArgs[0] 的值就是 187

如果没有设置searchSuggestSelection。一样搜索'187',那么suggest发起的uri就是:

content://com.mengqi.base.provider/newsearch/search_suggest_query/187?limit=50并且selectionArgs为null


searchSuggestThreshold表示suggest展示需要最小位数,这我设置的是2.那么我只搜索‘1’那么不会显示。搜索‘18’才开始有显示。(要显示必须是suggest的查询有数据可以返回哈)。

searchSuggestIntentAction 表示展示的suggest的item点击 点击触发一个intent,这个intent的action就是在这设置。

具体这个跳转后面还有详细讲到。

searchableInfo还有配置完成。还要到AndroidManifest.xml继续设置。

<activity android:name="com.mengqi.base.ui.search.SearchActivity"
		          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.default_searchable"
                   android:value="com.mengqi.base.ui.search.SearchActivity" />


其中searchActivity就是search的结果展示界面。就是点击键盘右下角的搜索键跳转的界面。

/**
 * CopyRight	2014 ZhuYan
 *	@author Zhu Yan
 *  
 *	All right reserved
 *	
 *	Created	on	2014-2-20  下午2:59:04
 */
package com.mengqi.base.ui.search;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import com.mengqi.base.R;
import com.mengqi.base.adapter.SearchAdapter;

/**
 * @author Zhu Yan
 *
 * Created	on	2014-2-20  下午2:59:04
 */
public class SearchActivity extends SherlockFragmentActivity implements LoaderCallbacks<Cursor>,OnItemClickListener
{
	private final static String TAG = "SearchActivity";
	
	private final static String ACTION_VIEW = "com.mengqi.base.view";
	
	private SearchAdapter adapter;
	private ListView listView;
	
	private String query = null;
	

	/**
	 * @return the query
	 */
	public String getQuery()
	{
		return query;
	}

	@Override
    protected void onCreate(Bundle arg0)
    {
		super.onCreate(arg0);

		// get and process search query here
		if(!handlerIntent(getIntent())){
			finish();
			return;
		}
		
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		setContentView(R.layout.fragment_empty_list);

		listView = (ListView) findViewById(android.R.id.list);
		//虽然我的search结果界面的 跟Suggest的item ui很想但是。这个adpter跟suggest没有关系。我是模仿suggest写的ui
		adapter = new SearchAdapter(this);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(this);
    }

	/**
	 * 
	 * @param intent 
	 * @return  如果是suggest的item点击跳转那么返回false,是展示搜索结果 返回true
	 */
    private boolean handlerIntent(Intent intent)
    {
        final String queryAction = intent.getAction();
        if (Intent.ACTION_SEARCH.equals(queryAction)) {
//            doSearchQuery(queryIntent, "onCreate()");
        	query = intent.getStringExtra(SearchManager.QUERY);
        	System.out.println( "handlerIntent " +query);
        	getSupportLoaderManager().restartLoader(0, null, this);
        	return true;
        }else {
        	System.out.println(queryAction);
        	System.out.println("data:"+intent.getDataString());
        	redirectToActivity(intent.getDataString());
        	return false;
        }
    }

	/**
	 * @param dataString
	 */
    private void redirectToActivity(String data)
    {
    	//根据传入的data做出不同的跳转。data来自query查询
    }

	@Override
    protected void onNewIntent(Intent intent)
    {
		// get and process search query here
		handlerIntent(intent);
	    super.onNewIntent(intent);
    }
	
	
	//我的searchActivity的actionbar一样有searchview控件
	@Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
	getSupportMenuInflater().inflate(R.menu.search, menu);
	SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setQueryHint(getString(R.string.search_hint));
	return super.onCreateOptionsMenu(menu);
    }
	
	

	@Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
		switch (item.getItemId()) {
//	        case R.id.menu_search:
//	        	System.out.println( "click search");
//	            onSearchRequested();
//	            return true;
	        case android.R.id.home:
	        	finish();
	            return true;
		}
	    return super.onOptionsItemSelected(item);
    }

	@Override
    public Loader<Cursor> onCreateLoader(int id, Bundle arg1)
    {
//		System.out.println( "create loader()");
		if(id == 0){
			return new SearchLoader(SearchActivity.this);
		}
	    return null;
    }

	@Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor)
    {
//		System.out.println( "no loader finished()");
		adapter.changeCursor(cursor);
    }
	
	//主要是销毁 activity的时候 关闭cursor
	@Override
    protected void onDestroy()
    {
		if(adapter != null){
			adapter.changeCursor(null);
		}
	    super.onDestroy();
    }

	@Override
    public void onLoaderReset(Loader<Cursor> loader)
    {
		loader.reset();
    }


	@Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id)
    {
		Object object = adapter.getItem(position);
		if(object != null && object instanceof Cursor){
			Cursor cursor = (Cursor) object;
			//我的search查询和suggest的返回的数据一样。后面有讲到suggest查询的数据返回
			redirectToActivity(cursor.getString(cursor
					.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_INTENT_DATA)));
		}
    }

}


好了现在就是配置suggest的数据模型。suggest因为adapter都是系统提供的。所以我们给suggest查询返回的cursor必须是固定数据格式的。

private final static String[] SearchQuery = new String[]{BaseColumns._ID,
				SearchManager.SUGGEST_COLUMN_TEXT_1,SearchManager.SUGGEST_COLUMN_TEXT_2,
				SearchManager.SUGGEST_COLUMN_ICON_1,SearchManager.SUGGEST_COLUMN_INTENT_DATA};

这就是我的suggest查询的数据库表项。

_id是必须要的。而且每一项都不一样。

SearchManager.SUGGEST_COLUMN_TEXT_1,是指suggest显示的item的标题。SearchManager.SUGGEST_COLUMN_TEXT_2是副标题。

SearchManager.SUGGEST_COLUMN_ICON_1是指显示的ICON  这个值可以是R.drawable的id值。或者是资源文件的URI。

SearchManager.SUGGEST_COLUMN_INTENT_DATA 是值我们点击suggest的item时候 产生一个intent。intent的action就是在searchable.xml设置的。

intent携带的数据就是这个表象的值。这个值通过intent.getDataString();获取。点击suggest的item产生的item会传递到searchActivity进行处理。

所以在SearchActivity中我有handlerIntent()方法对点击suggest的item或者是点击search进行区分处理。

如果你是要对suggest查询的数据库表没有刚才的 表项可以用别名查询。简单举例:select id as _id,name as suggest_text_1 from .....

如果你是多张表查询让后放到suggest中。我这边想到的是查询表 然后得到cursor 然后读取cursor的数据放到MatrixCursor中。反复操作。最后返回MatrixCursor。


SearchActivity还用到了Loader  看不明白就去查询一下吧。


这个是官网的SearchView讲解,比我说的详细。

http://developer.android.com/guide/topics/search/adding-custom-suggestions.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值