How can I use VectorDrawable with the Android Toolbar? - android

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 %)

Related

Animating the selected icon on BottomNavigationView

I was looking at animating the VectorDrawables I currently use in my BottomNavigationView when a tab is selected like in this Material Product Study for the Owl app. However unlike for the Toolbar view when I get the icon using MenuItem.getIcon(), cast it to AnimatedVectorDrawable and call the animate() method, there is no animation.
I was wondering if there is anything I could do to achieve this, if this will be likely included in the stable Material Components library or if I am better off creating a custom view extending the BottomNavigationView class.
we can animate the bottomnavigationview icon using below code:
bottomNavigationId.menu.getItem(i).icon =
AnimatedVectorDrawableCompat.create(this, R.drawable.ic_settings_active_avd)
val anim = bottomNavigationId.menu.getItem(i).icon as Animatable
anim.start()
but this is not working api > 24
So, better approach is create an AnimatedStateListDrawable where the AVD is the transition used into android:state_checked="true". Then you can just set this as the drawable on the MenuItem and it will run the AVD when the item is selected.
Eg:
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:targetApi="16">
<item android:id="#+id/state_on"
android:drawable="#drawable/ic_settings_active"
android:state_checked="true"/>
<item android:id="#+id/state_off"
android:drawable="#drawable/ic_settings_inactive"/>
<transition
android:drawable="#drawable/ic_settings_active_avd"
android:fromId="#id/state_off"
android:toId="#id/state_on" />
</animated-selector>
Use this animated state list drawable as icon in menu
<?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/item_settings_fragment"
android:icon="#drawable/anim_settings"
android:title="#string/settings"
app:showAsAction="always" />
...
</menu>
Checkout below link for complete understanding bottomnavigationview with animated drawables
https://medium.com/#naththeprince/delightful-animations-in-android-d6e9c62a23d3
It's currently not possible to use animated icons with BottomNavigationView. We have had this feature request submitted internally, but have deprioritized work on it.
If you would like to help add support we'd gladly accept a pr at https://github.com/material-components/material-components-android
Make an animated vector drawable by using Shape Shifter
Add this line in build.gradle(Module:app)
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
Make Drawable selector file - selector_search.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="16">
<item
android:id="#+id/state_on"
android:drawable="#drawable/avd_search"
android:state_checked="true" />
<item
android:id="#+id/state_off"
android:drawable="#drawable/icon_search" />
<transition
android:drawable="#drawable/avd_search"
android:fromId="#id/state_off"
android:toId="#id/state_on" />
</animated-selector>
avd search is animated vector drawable file
icon_search is normal drawable file
Use this drawable selector file as icon in menu
<?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/navigation_search"
android:icon="#drawable/selector_search"
android:title="#string/search"
/>
</menu>
Enjoy

Make a API-dependent reference to a theme-style

API 21+:
android:background="?android:attr/selectableItemBackgroundBorderless"
API <21:
android:background="?android:attr/selectableItemBackground"
How is it possible?
I know the solution that uses "?attr/API_dependent_theme_reference" like this. This doesn't work for App Widget layout, unfortunately.
Also, I know the solution uses style="..." for the view and multiple style definitions in values and values-v21 folders. But looking for a way to directly assign the background property (especially as Android, unfortunately, don't support assigning multiple styles like CSS: class="style1 style2 etc"!).
You can have two custom drawables
drawable/backround_name.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="?android:attr/selectableItemBackground"
</layer-list>
and
drawable-v21/backround_name.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="?android:attr/selectableItemBackgroundBorderless"
</layer-list>

Why do I need to use app namespace in menu items when using AppCompat

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

getActionView() of my MenuItem return null in AppCompat

I had this menu xml that works fine:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:id="#+id/context_menu_save"
android:actionViewClass="my.app.TextViewPlus"
android:showAsAction="always"
android:title="#string/logout"
android:visible="false"/>
</menu>
But when i started using AppComap v7 i hade null exception when using getActionView().
I change my menu layout to:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/context_menu_save"
myapp:actionViewClass="my.app.TextViewPlus"
myapp:showAsAction="always"
android:title="#string/logout"
android:visible="false"/>
</menu>
And now it works fine. Can anyone explain, why is it happens?
xmlns:myapp this is used when you create your own (or use others) customized views.
xmlns:android this is used when default android views.
so as ur question, i hope ur using your own (or use others) customized views. so u got error.
In Android Studio v1.5, I see the following message for this scenario:
When using the appcompat library, menu resources should refer to the app: namespace, not the android: namespace.
When not using the appcompat library, you should be using the android: namespace.

android changing layer-list programmatically

I have this xml drawable:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+map/marker_frame"
android:drawable="#drawable/map_pointer_green"/>
<item android:id="#+map/marker_profile_picture"
android:drawable="#drawable/questionmark"/>
</layer-list>
how can I change the item attribute from code? How can I access its id?
I want to be able to change each of the drawables from code according to scenarios.
What if use LayerDrawable in your code

Categories

Resources