Issue
I have two tabs and each tabs has its own searchbar.
I bind the searchbar in onCreateOptionsMenu
. However, the searchbars only work if I leave the screen once and return to the screen (meaning it needs one more lifecycle for the searchbars to react). I confirmed that onCreateOptionsMenu is indeed called two times at the time of the creation of the ViewPagerFragment.
I bind them like this:
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;
}
});
I am guessing this bug is related to the tabs. How do implement a working searchbar with tabs (i.e. viewpager2)?
I call this on onCreateOptionsMenu:
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Call the above...
}
The ViewPager hosting them looks like this:
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();
}
Solution
OP and I were communicating while we found a solution.
First each fragment was changed to
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);
}
}
SearchView
was inflated by using a menu.xml file within the App's Activity.SearchView.OnQueryTextListener
was implemented by eachFragment
that needed access to theSearchView
- Since
onCreateOptionsMenu()
is invoked each time aFragment
is created, or subsequently comes into view (e.g. Swipe); theSearchView
'sOnQueryTextListener
is updated to the correspondingFragment
- Lastly, there was a line in OP's main
Fragment
containing theViewPager2
, which was removed:viewPager2.setOffscreenPageLimit(5);
that caused eachFragment
provided by theFragmentStateAdapter
to instantiate and mutate theSearchView
'sOnQueryTextListener
each time aFragment
was created. Removing the line made sure that only theFragment
that was in view was bound to theToolbar
'sSearchView
.
If any more code is desired, i'd be happy to post what I have, and if I come up with a solution using viewPager2.setOffscreenPageLimit(5);
i.e. caching, i'll post that as well
Answered By - clcuenca
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.