问题
Project demonstrating this bug: https://github.com/smarek/ActionBar-Navigation-Bug
Bugreport on b.android.com : http://code.google.com/p/android/issues/detail?id=51449
I'm currently facing an issue with ActionBar.
Let's have a ViewPager+PagerTitleStrip and 3 Fragments.
User flow:
- Open application
- First Fragment has set navigation mode to NAVIGATION_MODE_LIST
- Other Fragments has NAVIGATION_MODE_STANDARD
- All Fragments has options menu item with SearchView
- Go to second or third and open search (click on search item)
- Close search view or not (you can just swipe back to previous fragment)
- Go to first fragment, and see, there is no NAVIGATION_MODE_LIST
- On first fragment open search and close it
- Navigation list is visible again
Adding just the code of MainActivity and layout the project is standard Android Application Project, minSdk 11, when creating main activity, select blank activity and swipe views + title strip
layout/activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!--
This title strip will display the currently visible page title, as well as the page
titles for adjacent pages.
-->
<android.support.v4.view.PagerTitleStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
com/example/project/MainActivity.java
// imports ommited
public class MainActivity extends FragmentActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public static class DummySectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public static final int MENU_SEARCH = -1;
protected MenuItem searchItem;
protected SearchView mSearchView;
public DummySectionFragment() {
setHasOptionsMenu(true);
}
/*
* Initializing menu items, adding only searchItem (aka SearchView in actionview)
*/
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
mSearchView = new SearchView(getActivity().getActionBar()
.getThemedContext());
searchItem = menu
.add(Menu.NONE, MENU_SEARCH, Menu.NONE, "Search")
.setIcon(android.R.drawable.ic_menu_search)
.setActionView(mSearchView)
.setShowAsActionFlags(
MenuItem.SHOW_AS_ACTION_ALWAYS
| MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
textView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));
return textView;
}
// Using setUserVisibleHint to operate with actionbar
// (navigation mode) and visibility of option menu items
// if isVisibleToUser, we're doing setup for current Fragment
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// setting navigation mode according to fragment
ActionBar ab = getActivity().getActionBar();
int mode = 0;
// ARG_SECTION_NUMBER is argument with numbers 1, 2, 3
switch (getArguments().getInt(ARG_SECTION_NUMBER)) {
default:
case 1:
mode = ActionBar.NAVIGATION_MODE_LIST;
// Simple adapter added to spinner, to be visible
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_spinner_dropdown_item,
new String[] { "A", "B", "C" });
ab.setListNavigationCallbacks(spinnerArrayAdapter,
new OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(
int itemPosition, long itemId) {
return false;
}
});
break;
case 2:
case 3:
mode = ActionBar.NAVIGATION_MODE_STANDARD;
break;
}
getActivity().getActionBar().setNavigationMode(mode);
} else {
// resetting navigation mode
if (getActivity() != null
&& getActivity().getActionBar() != null)
getActivity().getActionBar().setNavigationMode(
ActionBar.NAVIGATION_MODE_STANDARD);
}
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return 3;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase();
case 1:
return getString(R.string.title_section2).toUpperCase();
case 2:
return getString(R.string.title_section3).toUpperCase();
}
return null;
}
}
}
回答1:
Bug
I am posting this just to point the discussion in the direction of the bug.
The bug is more related to the SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
flag. Once you remove the flag, everything will work perfectly. It is most probably a bug but once again I am not sure if there is a rational explanation.
Solution (not really)
When you're creating the menu item in onCreateOptionsMenu
, remove the ORed MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
Simply, change this
searchItem = menu
.add(Menu.NONE, MENU_SEARCH, Menu.NONE, "Search")
.setIcon(android.R.drawable.ic_menu_search)
.setActionView(mSearchView)
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS
| MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
to
searchItem = menu
.add(Menu.NONE, MENU_SEARCH, Menu.NONE, "Search")
.setIcon(android.R.drawable.ic_menu_search)
.setActionView(mSearchView)
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
Bug without viewpager
I have forked the project and here it is without the viewpager with the same behaviour ActionBar-Navigation-Bug
回答2:
I had a similar problem when the SearchView had the SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW flag set. My workaround was to expand and collapse the MenuItem of the SearchView after switching to the NAVIGATION_MODE_LIST:
actionBar.setNavigationMode( ActionBar.NAVIGATION_MODE_LIST );
actionBar.setDisplayShowTitleEnabled( false );
searchMenuItem.expandActionView();
searchMenuItem.collapseActionView();
It is kind of dirty but it did the job for me.
Btw... The same bug and solution also applies to ActionBarSherlock.
回答3:
Here is how I got round this bug:
First I made the MenuItem global in the activity:
private MenuItem searchItem;
In the activity I had the following method:
public void hideSearch()
{
MenuItemCompat.collapseActionView(searchItem);
}
Then in the onCreateView() method of the fragment I call this method, just before returning the view. My spinner then stopped being hidden. To be honest, Im not sure why this works, but it did for me.
来源:https://stackoverflow.com/questions/15002748/actionbar-bug-list-mode-navigation-not-visible-after-using-searchview