菜单栏添加搜索功能
- 布局添加
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="搜索"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom"/>
</menu>
配置
xml/searchable.xml
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:hint="搜索" android:label="@string/app_name"/>
AndroidMainifest.xml
<manifest package="com.xuie.sharedemo" xmlns:android="http://schemas.android.com/apk/res/android"> ... <uses-permission android:name="android.permission.READ_CONTACTS"/> <application > ... <activity android:name=".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> </application> </manifest>
加载搜索功能
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search, menu);
MenuItem item = menu.findItem(R.id.action_search);
searchView = (SearchView) MenuItemCompat.getActionView(item);
...
}
...
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
...
}
}
示例
搜索通讯录
package xxx;
import android.Manifest;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Toast;
import butterknife.Bind;
import butterknife.ButterKnife;
public class SearchActivity extends AppCompatActivity {
public static final String TAG = SearchActivity.class.getSimpleName();
int READ_CONTACTS_REQUEST_CODE = 11;
SearchView searchView;
SimpleCursorAdapter adapter;
Cursor cursor;
final String[] PROJECTION = new String[]{
ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER};
@Bind(R.id.list_view)
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ButterKnife.bind(this);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS},
READ_CONTACTS_REQUEST_CODE);
} else {
init();
}
}
private void init() {
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
PROJECTION,
null,
null,
null);
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2, cursor,
new String[]{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
ContactsContract.CommonDataKinds.Phone.NUMBER
},
new int[]{android.R.id.text1, android.R.id.text2},
0);
listView.setAdapter(adapter);
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
// 输入法如果是显示状态,那么就隐藏输入法
imm.hideSoftInputFromWindow(listView.getWindowToken(), 0);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
doNext(requestCode, grantResults);
}
private void doNext(int requestCode, int[] grantResults) {
if (requestCode == READ_CONTACTS_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
init();
} else {
// Permission Denied
finish();
}
}
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}
private void doMySearch(String query) {
Toast.makeText(this, "do search " + query, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search, menu);
MenuItem item = menu.findItem(R.id.action_search);
searchView = (SearchView) MenuItemCompat.getActionView(item);
/*
* 默认情况下, search widget是"iconified“的,只是用一个图标 来表示它(一个放大镜),
* 当用户按下它的时候才显示search box . 你可以调用setIconifiedByDefault(false)让search
* box默认都被显示。 你也可以调用setIconified()让它以iconified“的形式显示。
*/
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
/*
* 默认情况下是没提交搜索的按钮,所以用户必须在键盘上按下"enter"键来提交搜索.你可以同过setSubmitButtonEnabled(
* true)来添加一个提交按钮("submit" button)
* 设置true后,右边会出现一个箭头按钮。如果用户没有输入,就不会触发提交(submit)事件
*/
searchView.setSubmitButtonEnabled(true);
/*
* 初始是否已经是展开的状态
* 写上此句后searchView初始展开的,也就是是可以点击输入的状态,如果不写,那么就需要点击下放大镜,才能展开出现输入框
*/
// searchView.onActionViewExpanded();
// 设置search view的背景色
// searchView.setBackgroundColor(0xff000000);
/*
* 默认情况下, search widget是"iconified“的,只是用一个图标 来表示它(一个放大镜),
* 当用户按下它的时候才显示search box . 你可以调用setIconifiedByDefault(false)让search
* box默认都被显示。 你也可以调用setIconified()让它以iconified“的形式显示。
*/
searchView.setIconifiedByDefault(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
/*
* 在输入时触发的方法,当字符真正显示到searchView中才触发,像是拼音,在舒服法组词的时候不会触发
*
* @param queryText
*
* @return false if the SearchView should perform the default action
* of showing any suggestions if available, true if the action was
* handled by the listener.
*/
@Override
public boolean onQueryTextChange(String queryText) {
Log.d(TAG, "onQueryTextChange = " + queryText);
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY +
" LIKE '%" + queryText + "%' " +
" OR "
+ ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY +
" LIKE '%" + queryText + "%' ";
// String[] selectionArg = { queryText };
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
PROJECTION,
selection,
null,
null);
adapter.swapCursor(cursor); // 交换指针,展示新的数据
return true;
}
/*
* 输入完成后,提交时触发的方法,一般情况是点击输入法中的搜索按钮才会触发。表示现在正式提交了
*
* @param queryText
*
* @return true to indicate that it has handled the submit request.
* Otherwise return false to let the SearchView handle the
* submission by launching any associated intent.
*/
@Override
public boolean onQueryTextSubmit(String queryText) {
Log.d(TAG, "onQueryTextSubmit = " + queryText);
if (searchView != null) {
// 得到输入管理对象
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
// 这将让键盘在所有的情况下都被隐藏,但是一般我们在点击搜索按钮后,输入法都会乖乖的自动隐藏的。
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0); // 输入法如果是显示状态,那么就隐藏输入法
}
searchView.clearFocus(); // 不获取焦点
}
return true;
}
});
return true;
}
}