片段替换在搜索视图上触发查询文本更改



这是我浏览应用程序的方式:

  • 使用列表打开片段
  • 按在搜索视图中输入的文本筛选列表
  • 点击列表项(列表片段被详细片段取代(
  • 向后导航(详细信息片段被列表片段替换(

当我从列表片段导航到详细信息片段时,我想将搜索视图的当前过滤器保留在字符串变量中。我在执行 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.

我将菜单项属性showAsActionandroid: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;

        }

相关内容

  • 没有找到相关文章

最新更新