i'm try to apply actionbar in my android, i copied a menu xml from another app to current app (/res/layout/menu/actionbarmenu.xml)
here is the code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/media_play"
android:icon="#android:drawable/ic_media_play"
android:title="#string/media_play"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_pause"
android:icon="#android:drawable/ic_media_pause"
android:title="#string/media_pause"
android:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_previous"
android:icon="#android:drawable/ic_media_previous"
android:title="#string/media_previous"
android:showAsAction="ifRoom" />
<item android:id="#+id/media_next"
android:icon="#android:drawable/ic_media_next"
android:title="#string/media_next"
android:showAsAction="ifRoom">
</item>
</menu>
In every line "ifRoom|withText", there is a red underline appear and with yellow box :
Should use app:showAsAction with the appcompat library with
xmlns:app="http://schemas.android.com/apk/res/auto"
Anyone know what is the problem?
You should use app namespace for menu which is part of appcompat.
<?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/media_play"
android:icon="#android:drawable/ic_media_play"
android:title="#string/media_play"
app:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_pause"
android:icon="#android:drawable/ic_media_pause"
android:title="#string/media_pause"
app:showAsAction="ifRoom|withText"/>
<item android:id="#+id/media_previous"
android:icon="#android:drawable/ic_media_previous"
android:title="#string/media_previous"
app:showAsAction="ifRoom" />
<item android:id="#+id/media_next"
android:icon="#android:drawable/ic_media_next"
android:title="#string/media_next"
app:showAsAction="ifRoom">
</item> </menu>
The android:showAsAction has been added in API 11 and your app has probably lower minimum API level. You can use the AppCompat library which will provide this parameter and its desired behavior, however, to reffer the AppCompat parameter you have to call it within the right XML namespace.
The namespace is included by the suggested code added to root <menu> tag
xmlns:app="http://schemas.android.com/apk/res/auto"
and then you can add app:showAsAction to your <item> tags
Related
What is the proper method to use the new VectorDrawable in the toolbar?
I tried to use the app:srcCompat element as illustrated below, but nothing showed up.
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
app:srcCompat="#drawable/ic_clear"
app:showAsAction="ifRoom" />
</menu>
I have my own toolbar layout using android.support.v7.widget.Toolbar and Android Support Library v23.2 on JB (16).
Turns out it's quite easy.
Say, you have vector drawable vd_trash_24dp.
Describing MenuItem one cannot address VectorDrawable directly with android:icon. It seems ignoring app:srcCompat also.
But. As all we know ;)
AppCompat does support loading vector drawables when they are
referenced in another drawable container such as a StateListDrawable,
InsetDrawable, LayerDrawable, LevelListDrawable, and RotateDrawable
Let's try it, should we?
Create StateListDrawable vd_test_vd
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/vd_trash_24dp" />
</selector>
than
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item android:id="#+id/menu_action_filter"
android:title="#string/menu_action_filter"
android:icon="#drawable/vd_test_vd"
android:orderInCategory="100"
app:showAsAction="always"/>
</menu>
street magic indeed.
Yes, one could try and set drawable at runtime with MenuItem.setIcon(). But who need that %)
Previously, before using AppCompat, I was using SherlockActionBar to support Android 2.3.
The following menu works just perfect under SherlockActionBar
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/menu_browser"
android:title="#string/menu_browser"
android:showAsAction="ifRoom"
android:icon="?attr/actionBarBrowserIcon"/>
<item
android:id="#+id/menu_share"
android:title="#string/menu_share"
android:showAsAction="ifRoom"
android:icon="?attr/actionBarShareIcon"/>
</menu>
However, even since migrating to AppCompat, I realize the above menu doesn't work. I need to use app namespace, in order to make it work.
<?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/menu_browser"
android:title="#string/menu_browser"
app:showAsAction="ifRoom"
android:icon="?attr/actionBarBrowserIcon"/>
<item
android:id="#+id/menu_share"
android:title="#string/menu_share"
app:showAsAction="ifRoom"
android:icon="?attr/actionBarShareIcon"/>
</menu>
Why is this so? What is the difference comparing to SherlockActionBar, which makes app namespace unnecessary?
Attributes provided by libraries (or by the app itself) are suppose to be namespaced in order to avoid conflicts/collisions.
ActionBarSherlock masks this behavior by naming the attribute android:showAsAction. (As opposed to a showAsAction attribute in the android namespace): https://github.com/JakeWharton/ActionBarSherlock/blob/master/actionbarsherlock/res/values/abs__attrs.xml
I'm trying to use the Icons of the Sherlock Actionbar in my menu XML-File but I can't figure the right namespace out.
I tried com.sherlock and com.sherlock.R but nothing seemed to work. I couldn't find documentation on that either!
That's what I tried:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sherlock="http://schemas.android.com/apk/res/com.actionbarsherlock.R" >
<item
android:id="#+id/action_refresh"
android:orderInCategory="99"
android:showAsAction="ifRoom"
android:icon="#sherlock:drawable/action_refresh"
android:title="#string/action_refresh"
/>
</menu>
But that just fails with an error message that the icon couldn' be found.
Error: No resource found that matches the given name (at 'icon' with value '#sherlock:drawable/action_refresh')
Any ideas how to get the correct namespace?
you no need to put the namespace. use the below code
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_refresh"
android:orderInCategory="99"
android:showAsAction="ifRoom"
android:icon="#drawable/action_refresh"
android:title="#string/action_refresh"
/>
</menu>
i want to add customs icons to my option menu, like that :
How can i do that with custom icons in my menu.xml ?
Or if you know the list of defaults icons, i am interested by that...
Here is my actual menu.xml code :
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_settings"
android:title="#string/menu_settings"
android:orderInCategory="100"
android:showAsAction="never" >
</item>
<item android:id="#+id/item1" android:title="Accueil" android:titleCondensed="Accueil" android:icon="#android:drawable/ic_menu_home"></item>
</menu>
Thanks !
Inside of the item tag, use android:icon="#drawable/your_icon". That should work.
I want to have 2 selectable themes for my application. In order to do that, I defined some attributes, like this:
<attr format="color" name="item_background" />
Then, I created both themes, like this:
<style name="ThemeA">
<item name="item_background">#123456</item>
</style>
<style name="ThemeB">
<item name="item_background">#ABCDEF</item>
</style>
This method works great, allowing me to create and modify several themes easily. The problem is that it seems that it can be used only in Views, and not in Drawables.
For example, referencing a value from a View inside a layout works:
<TextView android:background="?item_background" />
But doing the same in a Drawable doesn't:
<shape android:shape="rectangle">
<solid android:color="?item_background" />
</shape>
I get this error when running the application:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
If instead of ?item_background I use a hardcoded color, it works, but that doesn't allow me to use my themes. I also tried ?attr:item_background, but the same happens.
How could I do this? And why does it work in Views but not in Drawables? I can't find this limitation anywhere in the documentation...
In my experience it is not possible to reference an attribute in an XML drawable.
In order to make your theme you need to:
Create one XML drawable per theme.
Include the needed color into you drawable directly with the #color tag or #RGB format.
Make an attribute for your drawable in attrs.xml.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Attributes must be lowercase as we want to use them for drawables -->
<attr name="my_drawable" format="reference" />
</resources>
Add your drawable to your theme.xml.
<style name="MyTheme" parent="#android:style/Theme.NoTitleBar">
<item name="my_drawable">#drawable/my_drawable</item>
</style>
Reference your drawable in your layout using your attribute.
<TextView android:background="?my_drawable" />
Starting with lollipop (API 21) this feature is supported, see
https://code.google.com/p/android/issues/detail?id=26251
However, if you're targeting devices without lollipop, don't use it, as it will crash, use the workaround in the accepted answer instead.
Although it's not possible to reference style attributes from drawables on pre-Lollipop devices, but it's possible for color state lists. You can use AppCompatResources.getColorStateList(Context context, int resId) method from Android Support Library. The downside is that you will have to set those color state lists programmatically.
Here is a very basic example.
color/my_color_state.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="?colorControlActivated" />
<item android:color="?colorControlNormal" />
</selector>
A widget that needs a color state list:
<RadioButton
android:id="#+id/radio_button"
android:text="My Radio" />
And the most important:
ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_color_state);
RadioButton r = (RadioButton) findViewById(R.id.radio_button);
r.setTextColor(csl);
Well, not the most elegant or shortest way, but this is what Android Support Library does to make it work on older versions (pre-Lollipop) of Android.
Unfortunately, the similar method for drawables doesn't work with style attributes.
I answered the same question in https://stackoverflow.com/a/59467269/3841352 but i will post it here as well:
I encountered the same problem and as of 2019 it hasn't been resolved so you can't have an attribute referenced in a selector as a drawable. I will share the solution I got for the problem as I don't see it posted in here. I found it in the last comment of the bug report.
The workaround is basically create a drawable resource that will be the one referring the attribute value.
To illustrate your case the solution would be instead of:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
<item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
<item android:drawable="#android:color/darker_gray" android:state_enabled="false"/>
<item android:drawable="?attr/colorPrimary"/>
</selector>
you would replace the ?attr/* for a drawable resource:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/colorPrimaryDrawable" android:state_enabled="true" android:state_window_focused="false"/>
<item android:drawable="#drawable/colorPrimaryDarkDrawable" android:state_pressed="true"/>
<item android:drawable="#android:color/darker_gray" android:state_enabled="false"/>
<item android:drawable="#drawable/colorPrimaryDrawable"/>
</selector>
The drawables would be defined as:
drawable/colorPrimaryDrawable
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
<solid android:color="?attr/colorPrimary" />
</shape>
drawable/colorPrimaryDarkDrawable
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
<solid android:color="?attr/colorPrimaryDark" />
</shape>
Hope it helps!!
As #marmor stated this is now supported on API 21. But for those us who need to support legacy versions of Android, you can use this feature. Using the v7 support library you can still use it on apps with minimum SDK level all the way down to 7.
The AppCompatImageView in the v7 Android Support Library has a bug free implementation of this feature. Simply replace your usages of ImageView with AppCompatImageView.