Android Fragments 片段替换在searchview上触发onQueryTextChange

9w11ddsr  于 2023-08-06  发布在  Android
关注(0)|答案(9)|浏览(186)

这是我如何浏览我的应用程序:

  • 使用列表打开片段
  • 按searchview中输入的文本筛选列表
  • 点击listitem(列表片段被细节片段替换)
  • 向后导航(详细信息片段被列表片段替换)

当我从list-导航到detail-fragment时,我希望将searchview的当前过滤器保存在一个字符串变量中。我在执行onQueryTextChange时存储searchview的值。
问题是:我不能存储实际的过滤器值,因为当我从列表导航到细节时,onQueryTextChange被调用,因为某些东西清除了searchview的文本。

// ...
        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}


如何防止搜索视图在导航时被系统清除?

  • 谢谢-谢谢
jmo0nnb3

jmo0nnb31#

经过2天的谷歌搜索,我得到了解决方案,肯定会帮助你。
我只有cut and pasted代码从onCreateOptionMenu()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);
}


谢谢您的支持:)

wfauudbj

wfauudbj2#

问题是ActionBar(和子组件)在包含它的片段被替换时会折叠。发生这种情况时,SearchView查询将被清除,如onActionViewCollapsed中所示。解决方法包括:

防止崩溃

从searchview的创建代码中删除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;
}

字符串
这将是更好的选择,因为它不会影响搜索视图的功能。

blmhpbnm

blmhpbnm3#

我看到你还没有找到解决方案,我有相同的problem张贴here
我发现当调用invalidateOptionsMenu时,也会调用onQueryTextChange方法,因为View会在清除搜索后使用先前的值启动dispatchRestoreInstanceState。你叫invalidateOptionsMenu吗?
也许,onQueryTextChange中,您可以检查应用程序对象的某些当前状态的布尔值,以了解是否应该执行 * 方法content*。在我的例子中,我使用mDrawerLayout.isDrawerOpen(..)来允许搜索。
您还可以在您使用的每个类上实现SearchView.OnQueryTextListener,在Fragment或Main Activity类上,您可以在类的某处设置一个布尔模块变量,您将在onQueryTextChange.中检查该变量

huus2vyu

huus2vyu4#

我将菜单项属性showAsActionandroid:showAsAction="always|collapseActionView"修改为android:showAsAction="always"。现在,searchview的外观和行为发生了一些变化,但是searchQuery没有被清除!

<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>

字符串

jei2mxaa

jei2mxaa5#

使用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
    }
})

字符串

3gtaxfhh

3gtaxfhh6#

如果有人遇到同样的问题,当SearchView当前展开时,在菜单XML文件中使用以下操作替换Fragment时,将触发onQueryTextChange回调:

android:showAsAction="always|collapseActionView"

字符串
当您尝试在onQueryTextChange回调中使用isVisible()(Java)或isVisible(Kotlin)作为确定片段是否实际可见的方法时,返回的值将始终返回true
这样做的原因是,当您尝试更改Fragment的SearchView当前展开时,将触发onQueryTextChange回调。
在此阶段,collapseActionView的默认动作是在更改Fragment的时候,折叠SearchView。

解决方案

只需调用您的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
    }
})

0h4hbjxa

0h4hbjxa7#

override fun onQueryTextChange(newText: String?): Boolean {
   // your codes
   if (!newText.isNullOrBlank()) {
      // when fragment change
      // this will not work
   }
   // your codes
   return true
}

字符串
当片段更改searchView触发时,我不知道为什么,但通过检查这个newText.isNullOrBlank(),我解决了我的问题,也许它可以帮助别人

eufgjt7s

eufgjt7s8#

不幸的是,所有提出的解决方案对我来说都没有帮助,因为我必须在SearchView上保留collapseActionView|ifRoom属性,并且我不想检查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检查我的Fragment当前是否正在从Activity中删除,并且我直接返回true,以便在片段被另一个片段删除/替换时“不做任何事情”。

70gysomp

70gysomp9#

这是我的解决方案:

@Override
        public boolean onQueryTextChange(final String newText) {

            if (searchTF.isIconified())
                return false;

            // put the "real" onQueryTextChange actions here

            return true;

        }

字符串

相关问题