Question

I am using ActionBarActivity from support library V7. However, when I specify android:showAsAction="always" in the menu xml, it does not take effect. I have to do it in the Java code in the method onCreateOptionsMenu(), to find the item and set the property manually. Is there anything wrong with my code? Why does this happen?

Here is my activity code, most from the document sample:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(false);

        Tab tab = actionBar
                .newTab()
                .setText("ArtistFragment")
                .setIcon(android.R.drawable.ic_input_add)
                .setTabListener(
                        new TabListener<ArtistFragment>(this, "ArtistFragment", ArtistFragment.class));
        actionBar.addTab(tab);

        tab = actionBar
                .newTab()
                .setText("AlbumFragment")
                .setIcon(android.R.drawable.btn_radio)
                .setTabListener(
                        new TabListener<AlbumFragment>(this, "AlbumFragment", AlbumFragment.class));
        actionBar.addTab(tab);
    }

    public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
        private Fragment mFragment;
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;

        /** Constructor used each time a new tab is created.
          * @param activity  The host Activity, used to instantiate the fragment
          * @param tag  The identifier tag for the fragment
          * @param clz  The fragment's Class, used to instantiate the fragment
          */
        public TabListener(Activity activity, String tag, Class<T> clz) {
            mActivity = activity;
            mTag = tag;
            mClass = clz;
        }

        /* The following are each of the ActionBar.TabListener callbacks */

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            // Check if the fragment is already initialized
            if (mFragment == null) {
                // If not, instantiate and add it to the activity
                mFragment = Fragment.instantiate(mActivity, mClass.getName());
                mFragment.setHasOptionsMenu(true); //MUST manually set here
                ft.add(android.R.id.content, mFragment, mTag);
            } else {
                // If it exists, simply attach it in order to show it
                ft.attach(mFragment);
            }
        }

        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            if (mFragment != null) {
                // Detach the fragment, because another one is being attached
                ft.detach(mFragment);
            }
        }

        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            // User selected the already selected tab. Usually do nothing.
        }
    }

    public static class ArtistFragment extends Fragment {
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.menu1, menu);
            // Manually set will take effect
            menu.findItem(R.id.menu_item1)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }
    }

    public static class AlbumFragment extends Fragment {
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.menu2, menu);
            // XML set android:showAsAction="always" does not work
        }
    }
}

And here are the two menu xml files:

menu1.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_item1"
        android:icon="@android:drawable/ic_menu_view"
        android:title="menu1"
        android:showAsAction="always"/>
</menu>

And menu2.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menu_item2"
        android:icon="@android:drawable/ic_menu_view"
        android:title="menu2"
        android:showAsAction="always"/>
</menu>
Was it helpful?

Solution

Problem solved, thanks to the answer posted at THIS PAGE

The trick is that I have to modify my menu xml file as this:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mytest="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item1"
        android:icon="@android:drawable/ic_media_ff"
        android:title="menu1"
        mytest:showAsAction="always"/>
</menu>

From the official document, there is a explanation of why this is necessary:

Using XML attributes from the support library

Notice that the showAsAction attribute above uses a custom namespace defined in the tag. This is necessary when using any XML attributes defined by the support library, because these attributes do not exist in the Android framework on older devices. So you must use your own namespace as a prefix for all attributes defined by the support library.

OTHER TIPS

My problem solved with this code : I modified android:showAsAction="always" with app:showAsAction="always" and my problem is solved

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_add_projects"
        app:showAsAction="always"
        android:icon="@drawable/ic_action_add_project"
        android:title="@string/add_project" />
</menu>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top