如何在辅助工具栏上为 SearchView 设置 MenuItemClickListener
How to set the MenuItemClickListener for a SearchView at a secondary Toolbar
我花了几个小时尝试在底部(次要)android.support.v7.widget.ToolBar 中设置一个简单的 android.support.v7.widget.SearchView。
我已经在顶部使用另一个工具栏设置为 ActionBar,所以我不能在 activity 上使用 onCreateOptionsMenu
回调,而我必须设置一个 OnMenuItemClickListener()
。我已阅读 the Android SearchView Tutorial, this tutorial 关于工具栏的内容。
相关代码,
简化的 HomepageActivity
package something.somethingelse.activities;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
public class HomepageActivity extends AppCompatActivity {
protected static final String TAG = "HomepageActivity";
private Toolbar mTopToolbar;
private Toolbar mBottomToolbar;
private FloatingActionButton mFab;
private Context mContext;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTopToolbar = (Toolbar) findViewById(R.id.topToolbar);
setSupportActionBar(mTopToolbar);
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (menuItem != null) {
Log.d(TAG, "menuItem != null");
searchView = (SearchView) menuItem.getActionView();
}
if (searchView != null) {
Log.d(TAG, "searchView != null");
searchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
searchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
mBottomToolbar.setVisibility(View.GONE);
return false;
}
});
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String arg0) {
Log.d(TAG, "Submited: "+arg0);
return false;
}
@Override
public boolean onQueryTextChange(String arg0) {
Log.d(TAG, "Changed: "+arg0);
return false;
}
});
return false;
}
});
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
简化主页布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.Toolbar
android:id="@+id/topToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@color/white"
guide:elevation="4dp"
android:minHeight="?attr/actionBarSize"
guide:theme="@style/Toolbar_Theme" >
<ImageView
android:id="@+id/ivAb_logo"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="58dp"
android:paddingTop="10dp"
android:src="@drawable/generic_logo" />
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/topToolbar" >
<RelativeLayout
android:id="@+id/homepage_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/homepage_background"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:id="@+id/bottomToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/primaryDark"
guide:elevation="4dp" />
</RelativeLayout>
<!-- The navigation drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="220dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:background="#60BBBBBB"
android:choiceMode="singleChoice"
android:divider="#FFFFFF"
android:dividerHeight="1px" />
</android.support.v4.widget.DrawerLayout>
菜单bottom_toolbar.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:title="@string/search"
android:icon="@drawable/ic_search_white"
guide:actionViewClass="android.support.v7.widget.SearchView"
guide:showAsAction="always">
</item>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search"
android:label="@string/app_name"
/>
AndroidManifest.xml 相关部分
<activity
android:name="something.somethingelse.activities.HomepageActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/Theme.Default" >
<intent-filter>
<action android:name="something.somethingelse.activities.HomepageActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
如果我 运行 那样,我会得到一个 SearchView 但没有我的 android:icon="@drawable/ic_search_white"
,而是我得到 google SearchView 图标,如果我点击它我会得到一个很好的编辑文本,具有清除和搜索功能,但无论我输入或按什么,Toolbar.OnMenuItemClickListener
内的 Log.d 的 NONE 都会被触发。 (由于声誉原因,我无法 post 图片)。
如果我使用 android:actionViewClass="android.support.v7.widget.SearchView"
而不是 guide:actionViewClass="android.support.v7.widget.SearchView"
我会得到我的 android:icon="@drawable/ic_search_white"
,如果我点击它,我会在 searchView.setOnCloseListener(new OnCloseListener() {
上得到一个 NPE 因为 searchView
是 null 。
我尝试在 this related question here, and this 上做些什么,但到目前为止没有成功。
更新时间 23/09/15
我找不到任何好的解决方案,所以,因为我只想获取 SearchView 项目,所以我决定像这样破解它:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.dlHomepageSpace, HomepageFragment.newInstance(mLanguage), HOMEPAGE_BUTTONS_TAG);
fragmentTransaction.commit();
}
mSearchState = SearchState.NOSEARCH;
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
// Here we set the search view toolbar functions
if(mBottomToolbar.getMenu().size() > 0){
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1);
mSearchView = (SearchView) searchMenuItem.getActionView();
if (mSearchView != null) {
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
mSearchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Log.d(TAG, "onClose");
mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1).collapseActionView();
switchToFab();
return false;
}
});
MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
Log.d(TAG, "onMenuItemActionExpand");
return true; // KEEP IT TO TRUE OR IT DOESN'T OPEN !!
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
Log.d(TAG, "onMenuItemActionCollapse");
switchToFab();
return true;
}
});
}
}
@Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent");
if(isSearchAction(intent)){
ArrayList<Detail> list = (ArrayList<Detail>) getListData(intent.getStringExtra(SearchManager.QUERY));
if(list.isEmpty()){
Toast.makeText(this, R.string.no_search_results_en, Toast.LENGTH_LONG).show();
}
} else {
ExtendedListFragment searchFragment = (ExtendedListFragment) getSupportFragmentManager().findFragmentByTag(HOMEPAGE_SEARCH_TAG);
mResultsList = list;
mSearchState = SearchState.SEARCH_LIST_SCREEN;
if(searchFragment==null){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.dlHomepageSpace, ExtendedListFragment.newInstance(list), HOMEPAGE_SEARCH_TAG);
fragmentTransaction.commit();
} else {
searchFragment.setDetailList(list);
}
}
}
}
private boolean isSearchAction(Intent intent) {
Log.d(TAG, "handleIntent");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.d(TAG, "ACTION_SEARCH");
return true;
}
return false;
}
本质上,我只是查看工具栏,并将唯一的项目放入其中,将其转换为 MenuItem,然后将 SearchView 作为 MenuItem 的 ActionView。
就像它一样有效,我不必使用 setOnMenuItemClickListener()
。当我点击视图时,我可以在其中输入内容(我不需要 mSearchView.OnQueryTextListener
但是,我已经看到它在工作),当我按下键盘上的放大镜时,我得到 onNewIntent()
调用正在工作。
我花了几个小时尝试在底部(次要)android.support.v7.widget.ToolBar 中设置一个简单的 android.support.v7.widget.SearchView。
我已经在顶部使用另一个工具栏设置为 ActionBar,所以我不能在 activity 上使用 onCreateOptionsMenu
回调,而我必须设置一个 OnMenuItemClickListener()
。我已阅读 the Android SearchView Tutorial, this tutorial 关于工具栏的内容。
相关代码, 简化的 HomepageActivity
package something.somethingelse.activities;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
public class HomepageActivity extends AppCompatActivity {
protected static final String TAG = "HomepageActivity";
private Toolbar mTopToolbar;
private Toolbar mBottomToolbar;
private FloatingActionButton mFab;
private Context mContext;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTopToolbar = (Toolbar) findViewById(R.id.topToolbar);
setSupportActionBar(mTopToolbar);
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (menuItem != null) {
Log.d(TAG, "menuItem != null");
searchView = (SearchView) menuItem.getActionView();
}
if (searchView != null) {
Log.d(TAG, "searchView != null");
searchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
searchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
mBottomToolbar.setVisibility(View.GONE);
return false;
}
});
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String arg0) {
Log.d(TAG, "Submited: "+arg0);
return false;
}
@Override
public boolean onQueryTextChange(String arg0) {
Log.d(TAG, "Changed: "+arg0);
return false;
}
});
return false;
}
});
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
简化主页布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.Toolbar
android:id="@+id/topToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@color/white"
guide:elevation="4dp"
android:minHeight="?attr/actionBarSize"
guide:theme="@style/Toolbar_Theme" >
<ImageView
android:id="@+id/ivAb_logo"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="58dp"
android:paddingTop="10dp"
android:src="@drawable/generic_logo" />
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/topToolbar" >
<RelativeLayout
android:id="@+id/homepage_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/homepage_background"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:id="@+id/bottomToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/primaryDark"
guide:elevation="4dp" />
</RelativeLayout>
<!-- The navigation drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="220dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:background="#60BBBBBB"
android:choiceMode="singleChoice"
android:divider="#FFFFFF"
android:dividerHeight="1px" />
</android.support.v4.widget.DrawerLayout>
菜单bottom_toolbar.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:guide="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:title="@string/search"
android:icon="@drawable/ic_search_white"
guide:actionViewClass="android.support.v7.widget.SearchView"
guide:showAsAction="always">
</item>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search"
android:label="@string/app_name"
/>
AndroidManifest.xml 相关部分
<activity
android:name="something.somethingelse.activities.HomepageActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/Theme.Default" >
<intent-filter>
<action android:name="something.somethingelse.activities.HomepageActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
如果我 运行 那样,我会得到一个 SearchView 但没有我的 android:icon="@drawable/ic_search_white"
,而是我得到 google SearchView 图标,如果我点击它我会得到一个很好的编辑文本,具有清除和搜索功能,但无论我输入或按什么,Toolbar.OnMenuItemClickListener
内的 Log.d 的 NONE 都会被触发。 (由于声誉原因,我无法 post 图片)。
如果我使用 android:actionViewClass="android.support.v7.widget.SearchView"
而不是 guide:actionViewClass="android.support.v7.widget.SearchView"
我会得到我的 android:icon="@drawable/ic_search_white"
,如果我点击它,我会在 searchView.setOnCloseListener(new OnCloseListener() {
上得到一个 NPE 因为 searchView
是 null 。
我尝试在 this related question here, and this 上做些什么,但到目前为止没有成功。
更新时间 23/09/15 我找不到任何好的解决方案,所以,因为我只想获取 SearchView 项目,所以我决定像这样破解它:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.dlHomepageSpace, HomepageFragment.newInstance(mLanguage), HOMEPAGE_BUTTONS_TAG);
fragmentTransaction.commit();
}
mSearchState = SearchState.NOSEARCH;
mBottomToolbar = (Toolbar) findViewById(R.id.bottomToolbar);
mBottomToolbar.inflateMenu(R.menu.bottom_toolbar);
// Here we set the search view toolbar functions
if(mBottomToolbar.getMenu().size() > 0){
SearchManager searchManager = (SearchManager) HomepageActivity.this.getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1);
mSearchView = (SearchView) searchMenuItem.getActionView();
if (mSearchView != null) {
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(HomepageActivity.this.getComponentName()));
}
mSearchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Log.d(TAG, "onClose");
mBottomToolbar.getMenu().getItem(mBottomToolbar.getMenu().size()-1).collapseActionView();
switchToFab();
return false;
}
});
MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
Log.d(TAG, "onMenuItemActionExpand");
return true; // KEEP IT TO TRUE OR IT DOESN'T OPEN !!
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
Log.d(TAG, "onMenuItemActionCollapse");
switchToFab();
return true;
}
});
}
}
@Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent");
if(isSearchAction(intent)){
ArrayList<Detail> list = (ArrayList<Detail>) getListData(intent.getStringExtra(SearchManager.QUERY));
if(list.isEmpty()){
Toast.makeText(this, R.string.no_search_results_en, Toast.LENGTH_LONG).show();
}
} else {
ExtendedListFragment searchFragment = (ExtendedListFragment) getSupportFragmentManager().findFragmentByTag(HOMEPAGE_SEARCH_TAG);
mResultsList = list;
mSearchState = SearchState.SEARCH_LIST_SCREEN;
if(searchFragment==null){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.dlHomepageSpace, ExtendedListFragment.newInstance(list), HOMEPAGE_SEARCH_TAG);
fragmentTransaction.commit();
} else {
searchFragment.setDetailList(list);
}
}
}
}
private boolean isSearchAction(Intent intent) {
Log.d(TAG, "handleIntent");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.d(TAG, "ACTION_SEARCH");
return true;
}
return false;
}
本质上,我只是查看工具栏,并将唯一的项目放入其中,将其转换为 MenuItem,然后将 SearchView 作为 MenuItem 的 ActionView。
就像它一样有效,我不必使用 setOnMenuItemClickListener()
。当我点击视图时,我可以在其中输入内容(我不需要 mSearchView.OnQueryTextListener
但是,我已经看到它在工作),当我按下键盘上的放大镜时,我得到 onNewIntent()
调用正在工作。