ActionBar BUG: List mode navigation not visible after using SearchView

北城以北 提交于 2020-01-31 04:29:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!