安卓:选项卡和搜索栏

4

我有两个选项卡,每个选项卡都有自己的搜索栏。

我在 onCreateOptionsMenu 中绑定了搜索栏。然而,只有当我离开屏幕并返回屏幕时(也就是说,搜索栏需要再次生命周期才能起作用),搜索栏才能正常工作。我确认在 ViewPagerFragment 创建时 onCreateOptionsMenu 确实被调用了两次。

我像这样绑定它们:

MenuItem searchItem = menu.findItem(R.id.search);
searchItem.setVisible(true);

SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
   @Override
    public boolean onQueryTextSubmit(String query) {
          ...
          return false;
     }

     @Override
     public boolean onQueryTextChange(String newText) {
           ...
          return false;
     }
});

我猜测这个bug与标签有关。如何使用标签(即viewpager2)实现一个可工作的搜索栏?


我在onCreateOptionsMenu中调用这个函数:

public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    // Call the above...
}

承载它们的ViewPager如下所示:

private void init(View view) {
    ViewPager2 viewPager2 = view.findViewById(R.id.view_pager_fragment_view_pager);
    TabLayout tabLayout = view.findViewById(R.id.tab_layout_fragment_view_pager);
    viewPager2.setUserInputEnabled(true);

    viewPager2.setAdapter(new ViewPagerFragmentAdapter(ViewPagerFragment.this));
    viewPager2.setOffscreenPageLimit(5);

    new TabLayoutMediator
            (tabLayout, viewPager2,
                    (tab, position) -> tab.setText(titles[position])).attach();
}

听起来你的问题可能来自于你的 searchView,你在这方面做过一些研究吗? - Biscuit
看起来问题与两个片段调用(创建)菜单有关。在这种情况下,您应该使用活动来填充菜单并绑定搜索栏,并根据当前页面(片段)将事件分派到该片段。 - Froyo
我不认为我能做到这一点,因为我在每个片段中的onCreateOptionsMenu方法中调用了所有先前的方法 - 请参见我的更新问题。 - Josip Domazet
@Froyo,我在我的帖子中添加了更多信息。 - Josip Domazet
也许你应该将这部分代码移动到 onPrepareOptionsMenu 方法中,并在 viewPager 页面更改时调用 activity 的 invalidateOptionsMenu() 方法? - Bakhtiyor Begmatov
@BakhtiyorBegmatov 那也没有改变它。我仍然需要切换到另一个片段,然后再返回才能使其工作。我认为我在 onCreateOptionsMenu 或 onPrepareOptionsMenu 中进行的绑定会被某种方式覆盖(可能是由托管片段引起的)? - Josip Domazet
1个回答

2

我和OP在寻找解决方案时进行了沟通。

首先,每个片段都被更改为

public class MergedItemsFragment extends Fragment implements SearchView.OnQueryTextListener {

    /// ------------------------------
    /// SearchView.OnQueryTextListener

    @Override
    public boolean onQueryTextSubmit(String query) {
        // ...
        return false;

    }

    @Override
    public boolean onQueryTextChange(String newText) {
        // ...
        return false;

    }

    /// --------
    /// Fragment

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_merged_items, container, false);

    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        final MenuItem   searchItem = menu.findItem(R.id.search);
        final SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
        searchView.setOnQueryTextListener(this);

    }

}

  • 使用菜单文件在App的Activity中实现了SearchView的填充。
  • 需要访问SearchView的每个Fragment都要实现SearchView.OnQueryTextListener
  • 由于onCreateOptionsMenu()在每次创建Fragment或随后进入视图(例如Swipe)时被调用,所以SearchViewOnQueryTextListener会被更新为对应的Fragment
  • 最后,OP的主Fragment中包含ViewPager2的一行代码被删除:viewPager2.setOffscreenPageLimit(5); 这导致由FragmentStateAdapter提供的每个Fragment都会在创建Fragment时实例化并改变SearchViewOnQueryTextListener。删除该行代码确保只有处于视图中的Fragment绑定到ToolbarSearchView

如果需要更多的代码,我很乐意发布我所拥有的代码,并且如果我想出使用viewPager2.setOffscreenPageLimit(5);进行缓存的解决方案,我也会发布它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接