在 Fragment 中添加 SearchView
Adding SearchView in Fragment
正在尝试在操作栏中包含一个搜索视图。为此,我做了以下工作:
已在菜单文件夹中创建 MenuSearch.xml,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_search"
android:actionViewClass="Android.Support.V7.Widget.SearchView"
android:icon="@android:drawable/ic_menu_search"
android:showAsAction="always"
android:title="Search"/>
</menu>
在片段中包含方法 OnCreateOptionsMenu:
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
inflater.Inflate(Resource.Menu.MenuSearch, menu);
base.OnCreateOptionsMenu(menu, inflater);
var searchManager = (SearchManager) this.Activity.GetSystemService(Context.SearchService);
searchView = (SearchView) (menu.FindItem(Resource.Id.action_search).ActionView);
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));
}
并且我在片段的oncreate中设置了HasOptionsMenu = true;
。
使用上面的代码,我在行 searchView.SetSearchableInfo...
中得到空指针。不确定为什么会发生这种情况,尽管一切似乎都是正确的。
根据解决类似问题的一些建议,我还尝试了以下搜索视图选项。
var item = menu.FindItem (Resource.Id.action_search);
var searchItem = MenuItemCompat.GetActionView(item);
searchView = searchItem.JavaCast<Android.Support.V7.Widget.SearchView>();
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));
但是,我再次得到 searchView 为 null。
既然我已经尝试了可能的选项,我对为什么 searchview 变为 null 毫无头绪。
非常感谢任何帮助。
将您的 MenuSearch.xml 更改为
<?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:title="@string/app_name"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
然后在您的片段中添加 searchView.setOnQueryTextListener
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search_option_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = new SearchView(((MainActivity) mContext).getSupportActionBar().getThemedContext());
// MenuItemCompat.setShowAsAction(item, //MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | //MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
// MenuItemCompat.setActionView(item, searchView);
// These lines are deprecated in API 26 use instead
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
searchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
}
);
}
在我片段的 onCreateOptionsMenu 代码中
SearchManager searchManager =
(SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo =
searchManager.getSearchableInfo(getActivity().getComponentName());
searchItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setSearchableInfo( searchableInfo);
产生了以下错误信息:
java.lang.NullPointerException:尝试在空对象引用
上调用虚拟方法 'void android.support.v7.widget.SearchView.setSearchableInfo (android.app.SearchableInfo)'
我把menu.xmlandroid:actionViewClass改成app:actionViewClass后,问题就没有再出现了。
menu.xml :
<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="...">
<item
android:id="@+id/menu_search"
android:title="@string/menu_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom">
我解决了这个问题我想分享我对 searchView NullPointerException 的回答
我们需要从 Main 中删除以下方法 Activity
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return true;
并在 OnActivityCreated setHasOptionsMenu(true)
中使用内部片段
和覆盖方法
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.action_search:
// onCall(); //your logic
return true;
default:
return super.onOptionsItemSelected(item);
}
}
您的 search_options_menu.xml 应该如下所示:
<?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:title="@string/app_name"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
覆盖 onCreateOptionMenu 片段中的方法 setHasOptionsMenu(true);
在 onCreate() 片段中。
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search_option_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//Do search code here
return true;
}
});
}
答案已更新为 2018 年。抱歉,如果您使用的是 Kotlin Java。
您的 xml 菜单资源(例如 search_menu.xml):
<?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:title="@string/app_name"
android:icon="@drawable/ic_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
构建代码:
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
menu.clear()
inflater?.inflate(R.menu.search_menu, menu)
val searchView = SearchView((context as MainActivity).supportActionBar?.themedContext ?: context)
menu.findItem(R.id.action_search).apply {
setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW or MenuItem.SHOW_AS_ACTION_IF_ROOM)
actionView = searchView
}
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
return false
}
})
searchView.setOnClickListener {view -> }
}
您可能还需要将这一行放在 onCreate()
中(为我的片段工作)才能显示所有内容:
setHasOptionsMenu(true)
对于 2018 年底和 API >= 26
兼容(弃用警告)和格式正确的答案:
menu.xml
:
<?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:title="Search_change_me_with_proper_id"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"/>
</menu>
Java 里面的代码 ActivityFragment
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true); // Add this!
return inflater.inflate(R.layout.fragment_add_app, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_app, menu);
MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// Here is where we are going to implement the filter logic
return true;
}
});
}
或者作为 第二个选项 让 ActivityFragment
实现 SearchView.OnQueryTextListener
然后使用菜单搜索:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true); // Add this! (as above)
return inflater.inflate(R.layout.fragment_add_app, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_app, menu);
MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(this); // Fragment implements SearchView.OnQueryTextListener
}
@Override
public boolean onQueryTextChange(String query) {
// Here is where we are going to implement the filter logic
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
search_view.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(query: String?): Boolean {
adapter.filter.filter(query)
return true
}
})
并且不要在 Manifest 文件中为您的 activity 添加 intent 过滤器。
正在尝试在操作栏中包含一个搜索视图。为此,我做了以下工作:
已在菜单文件夹中创建 MenuSearch.xml,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_search"
android:actionViewClass="Android.Support.V7.Widget.SearchView"
android:icon="@android:drawable/ic_menu_search"
android:showAsAction="always"
android:title="Search"/>
</menu>
在片段中包含方法 OnCreateOptionsMenu:
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
inflater.Inflate(Resource.Menu.MenuSearch, menu);
base.OnCreateOptionsMenu(menu, inflater);
var searchManager = (SearchManager) this.Activity.GetSystemService(Context.SearchService);
searchView = (SearchView) (menu.FindItem(Resource.Id.action_search).ActionView);
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));
}
并且我在片段的oncreate中设置了HasOptionsMenu = true;
。
使用上面的代码,我在行 searchView.SetSearchableInfo...
中得到空指针。不确定为什么会发生这种情况,尽管一切似乎都是正确的。
根据解决类似问题的一些建议,我还尝试了以下搜索视图选项。
var item = menu.FindItem (Resource.Id.action_search);
var searchItem = MenuItemCompat.GetActionView(item);
searchView = searchItem.JavaCast<Android.Support.V7.Widget.SearchView>();
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));
但是,我再次得到 searchView 为 null。
既然我已经尝试了可能的选项,我对为什么 searchview 变为 null 毫无头绪。
非常感谢任何帮助。
将您的 MenuSearch.xml 更改为
<?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:title="@string/app_name"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
然后在您的片段中添加 searchView.setOnQueryTextListener
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search_option_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = new SearchView(((MainActivity) mContext).getSupportActionBar().getThemedContext());
// MenuItemCompat.setShowAsAction(item, //MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | //MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
// MenuItemCompat.setActionView(item, searchView);
// These lines are deprecated in API 26 use instead
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
searchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
}
);
}
在我片段的 onCreateOptionsMenu 代码中
SearchManager searchManager =
(SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo =
searchManager.getSearchableInfo(getActivity().getComponentName());
searchItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setSearchableInfo( searchableInfo);
产生了以下错误信息: java.lang.NullPointerException:尝试在空对象引用
上调用虚拟方法 'void android.support.v7.widget.SearchView.setSearchableInfo (android.app.SearchableInfo)'我把menu.xmlandroid:actionViewClass改成app:actionViewClass后,问题就没有再出现了。 menu.xml :
<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="...">
<item
android:id="@+id/menu_search"
android:title="@string/menu_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom">
我解决了这个问题我想分享我对 searchView NullPointerException 的回答
我们需要从 Main 中删除以下方法 Activity
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return true;
并在 OnActivityCreated setHasOptionsMenu(true)
中使用内部片段
和覆盖方法
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.action_search:
// onCall(); //your logic
return true;
default:
return super.onOptionsItemSelected(item);
}
}
您的 search_options_menu.xml 应该如下所示:
<?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:title="@string/app_name"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
覆盖 onCreateOptionMenu 片段中的方法 setHasOptionsMenu(true);
在 onCreate() 片段中。
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search_option_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//Do search code here
return true;
}
});
}
答案已更新为 2018 年。抱歉,如果您使用的是 Kotlin Java。
您的 xml 菜单资源(例如 search_menu.xml):
<?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:title="@string/app_name"
android:icon="@drawable/ic_search"
app:showAsAction="collapseActionView|ifRoom"
/>
</menu>
构建代码:
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
menu.clear()
inflater?.inflate(R.menu.search_menu, menu)
val searchView = SearchView((context as MainActivity).supportActionBar?.themedContext ?: context)
menu.findItem(R.id.action_search).apply {
setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW or MenuItem.SHOW_AS_ACTION_IF_ROOM)
actionView = searchView
}
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
return false
}
})
searchView.setOnClickListener {view -> }
}
您可能还需要将这一行放在 onCreate()
中(为我的片段工作)才能显示所有内容:
setHasOptionsMenu(true)
对于 2018 年底和 API >= 26
兼容(弃用警告)和格式正确的答案:
menu.xml
:
<?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:title="Search_change_me_with_proper_id"
android:icon="@drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"/>
</menu>
Java 里面的代码 ActivityFragment
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true); // Add this!
return inflater.inflate(R.layout.fragment_add_app, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_app, menu);
MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// Here is where we are going to implement the filter logic
return true;
}
});
}
或者作为 第二个选项 让 ActivityFragment
实现 SearchView.OnQueryTextListener
然后使用菜单搜索:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true); // Add this! (as above)
return inflater.inflate(R.layout.fragment_add_app, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_app, menu);
MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(this); // Fragment implements SearchView.OnQueryTextListener
}
@Override
public boolean onQueryTextChange(String query) {
// Here is where we are going to implement the filter logic
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
search_view.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(query: String?): Boolean {
adapter.filter.filter(query)
return true
}
})
并且不要在 Manifest 文件中为您的 activity 添加 intent 过滤器。