这是我浏览应用程序的方式:
- 使用列表打开片段
- 按在搜索视图中输入的文本筛选列表
- 点击列表项(列表片段被详细片段取代(
- 向后导航(详细信息片段被列表片段替换(
当我从列表片段导航到详细信息片段时,我想将搜索视图的当前过滤器保留在字符串变量中。我在执行 onQueryTextChange 时存储搜索视图的值。
问题:我无法存储实际的过滤器值,因为当我从列表导航到详细信息时,onQueryTextChange 被调用,因为某些内容清除了搜索视图的文本。
// ...
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
searchReceived(s);
return true;
}
});
// ...
public void searchReceived(String searchQuery)
{
this.stateHolder.searchQuery = searchQuery;
// more code...
}
当我想在导航时恢复过滤器时,它只是使用空字符串进行过滤,因为错误的值存储在this.stateHolder.searchQuery
中。
叠:
onQueryTextChange():139, EmployeeListFragment$1 {com.example.exampleapp.fragment}
onTextChanged():1153, SearchView {android.widget}
access$2000():92, SearchView {android.widget}
onTextChanged():1638, SearchView$11 {android.widget}
sendOnTextChanged():7408, TextView {android.widget}
setText():3816, TextView {android.widget}
setText():3671, TextView {android.widget}
setText():80, EditText {android.widget}
setText():3646, TextView {android.widget}
setQuery():511, SearchView {android.widget}
onActionViewCollapsed():1250, SearchView {android.widget}
collapseItemActionView():1662, ActionBarView$ExpandedActionViewMenuPresenter {com.android.internal.widget}
collapseItemActionView():1258, MenuBuilder {com.android.internal.view.menu}
clear():521, MenuBuilder {com.android.internal.view.menu}
doInvalidatePanelMenu():789, PhoneWindow {com.android.internal.policy.impl}
run():221, PhoneWindow$1 {com.android.internal.policy.impl}
如何防止系统在导航时清除搜索视图?
谢谢。
经过 2 天的谷歌搜索,我得到了肯定会对您有所帮助的解决方案。
我刚刚从onCreateOptionMenu()
cut and pasted
代码到onPrepareOptionMenu()
我不知道为什么会这样,我认为searchView
的听众不会因为您可以通过这种方式更改代码而NULL
。
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
getSherlockActivity().getSupportMenuInflater().inflate(R.menu.menu_all_order, menu);
searchView = (SearchView) menu.findItem(R.id.menu_all_order_search).getActionView();
searchView.setInputType(InputType.TYPE_CLASS_NUMBER);
searchView.setQueryHint("Enter Order No");
searchView.setOnQueryTextListener(this);
}
并删除:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
谢谢:)
问题是当替换包含它的片段时,操作栏(和子组件(会折叠。发生这种情况时,将清除 SearchView 查询,如 onActionViewCollapsed 所示。解决方法包括:
防止塌陷
从搜索视图的创建代码中删除setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
,或从其 xml 代码中删除android:showAsAction="collapseActionView"
。
这将影响视图的关闭/语音搜索按钮在尝试折叠视图时显示的方式/时间
也可以通过覆盖 SearchView 的 onActionViewCollapsed(( 方法来防止折叠,该方法什么都不做,但可以完成相同的操作。
适当时忽略查询更改
当片段无效(被替换(时,请忽略查询更改,否则会导致片段更改其保存的查询文本或布局(如果片段实际上没有视图内容,则更改布局将导致异常(。
public boolean onQueryTextChange(String newText) {
if (!isVisible()) {
// The fragment was replaced so ignore
return true;
}
// Text was actually changed, perform search
return true;
}
这将是更好的选择,因为它不会影响搜索视图的功能。
我看到你还没有找到解决方案,我在这里发布了同样的问题:
我发现当调用invalidateOptionsMenu
时,也会调用方法onQueryTextChange
因为例如,在您清除搜索后,视图启动dispatchRestoreInstanceState
以前的值。你打电话给invalidateOptionsMenu
也许?
也许,在 onQueryTextChange
中,您可以检查应用程序对象某些当前状态的布尔值,以了解是否应执行方法内容。就我而言,我使用mDrawerLayout.isDrawerOpen(..)
来允许搜索。
您也可以在您使用的每个类、Fragment
或 Main Activity 类上实现SearchView.OnQueryTextListener
,在类的某个地方,您可以设置一个布尔模块变量,您将在内部检查该变量onQueryTextChange.
我将菜单项属性showAsAction
从 android:showAsAction="always|collapseActionView"
修改为 android:showAsAction="always"
。现在,搜索视图的外观和行为发生了一些变化,但搜索查询没有被清除!
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/actionSearch"
android:icon="@android:drawable/ic_menu_search"
android:actionViewClass="android.widget.SearchView"
android:showAsAction="always"
android:title="@android:string/search_go"
/>
</menu>
使用 androidx.appcompat.widget.SearchView
+ LiveData
+ ViewModel
:
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
viewModel.setSearchQuery(query)
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
if(searchView.isIconified || !isVisible) {
// Don't call setSearchQuery when SearchView is collapsing/collapsed
return true
}
viewModel.setSearchQuery(newText)
return true
}
})
如果有人遇到同样的问题,则在当前展开 SearchView 时,在菜单 XML 文件中使用以下操作替换片段时,将触发 onQueryTextChange 回调:
android:showAsAction="always|collapseActionView"
当您尝试在 onQueryTextChange 回调中使用 isVisible(( (Java( 或 isVisible (Kotlin( 来确定 Fragment 是否真的可见时,返回的值将始终返回 true。
这样做的原因是,当您尝试更改片段时,当前展开搜索视图时,将触发onQueryTextChange回调。
在此阶段,折叠操作视图的默认操作是在更改片段时折叠搜索视图。
解决方案:
只需在 onQueryTextChange 回调中调用您的 SearchView !isIconified (Kotlin( 方法,并且仅在返回 false 时才设置您的逻辑,即 SearchView 当前已展开。完整示例如下所述:
yourSearchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
// Do search query here if you use a submit action
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
if (!yourSearchView.isIconified) {
// Don't execute your search query here when SearchView is
// currently open
return true
}
// Do search query here
return true
}
})
override fun onQueryTextChange(newText: String?): Boolean {
// your codes
if (!newText.isNullOrBlank()) {
// when fragment change
// this will not work
}
// your codes
return true
}
当片段更改搜索视图触发时,我不知道为什么,但通过检查此newText.isNullOrBlank()
我解决了我的问题,也许它可以帮助某人
不幸的是,所有提出的解决方案对我没有帮助,因为我必须将collapseActionView|ifRoom
属性保留在我的 SearchView 上,而且我不想检查我的 SearchView 查询的可空性/空性。
所以每次查询更改,或者片段被另一个片段替换时,都会执行onQueryTextChange
回调 -> 并清空查询(这会导致一些问题😬(所以我做了这个:
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
if (this@SearchFragment.isRemoving) {
return true
}
// [Statements here]
return true
}
})
我正在检查我的片段当前是否正在从带有isRemoving
的活动中删除,如果片段被另一个片段删除/替换,我直接返回true
以便"不执行任何操作"。
的解决方案:
@Override
public boolean onQueryTextChange(final String newText) {
if (searchTF.isIconified())
return false;
// put the "real" onQueryTextChange actions here
return true;
}