A couple of days ago the support library version v22.1.0 was released and among the new things I have seen DrawableCompat.
Now my question is what is the difference between DrawableCompat and a normal Drawable, what benefits does it bring and when and how to use it.
I have read Chris Banes' blog, but it is lacking to properly explain what this is and how it could be useful for developers.
Quoting the blog post in question:
The Drawable tinting methods added in Lollipop are super useful for letting you dynamically tint assets.
Here, tinting refers to the Theme.Material/Theme.AppCompat approach of using grayscale drawables and applying tints, like colorPrimary or colorAccent, to tie them into a custom theme for an app. This is used in lots of places, in particular many places where the accent color is seen.
Continuing with the blog post:
AppCompat had its own baked in implementation in the v21 support library and we’ve now extracted that into DrawableCompat in support-v4 for everyone to use.
Hence, DrawableCompat allows you to use the tint-the-grayscale image as appcompat-v7 does, for tinting drawables, going back to API Level 4. This is in contrast to the similar tinting methods available on Drawable starting with API Level 21. In particular, if you are creating custom widgets and using appcompat-v7, you might use DrawableCompat to allow your widgets to adopt the app's color scheme.
what is the difference between DrawableCompat and a normal Drawable
DrawableCompat departs from the typical ...Compat approach. Classes like NotificationCompat.Builder are replacements for their progenitors (e.g., Notification.Builder). In this case, DrawableCompat applies certain changes, like the tint, to another Drawable, where that other drawable is "wrapped" by DrawableCompat. DrawableCompat simply provides the API and the wrap/unwrap capabilities; it is the Drawable that you get from wrap() that you would use in your app, in lieu of using the original grayscale Drawable that you started with.
Related
So I have an app in which the user can select a color by choosing from a set of RadioButtons, I have used the ButtonTint XML attribute to color the buttons, but obviously this only works on API > 21/.
so my question is,
how to change the color of the RadioButtons on KitKat(API 19) and below?
I have tested a few methods from other stack overflow questions, but so far none have worked.
Use design support library (23.2.0 OR latest) and appcompatwidgets as below
Material Design for Pre-Lollipop Devices :
AppCompat (aka ActionBarCompat) started out as a backport of the
Android 4.0 ActionBar API for devices running on Gingerbread,
providing a common API layer on top of the backported implementation
and the framework implementation. AppCompat v21 delivers an API and
feature-set that is up-to-date with Android 5.0
Android Support Library 22.1 :
The ability to tint widgets automatically when using AppCompat is
incredibly helpful in keeping strong branding and consistency
throughout your app. This is done automatically when inflating layouts
- replacing Button with AppCompatButton, TextView with AppCompatTextView, etc. to ensure that each could support tinting. In
this release, those tint aware widgets are now publicly available,
allowing you to keep tinting support even if you need to subclass one
of the supported widgets.
This tint aware widgets are now publicly available, allowing you to keep tinting support even if you need to subclass one of the supported widgets.
From link above,
The full list of tint aware widgets at this time is:
AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView
I'm studying Material Theme and some things don't work in version lower than 21, like ripple effect, change the status bar color and primary text color, view elevation... even I using the v7 library.
For view elevation I tried ViewCompat.setElevation(view, value) and doesn't work. Anyone knows why and how I have to do?
For the ripple effect I tried to put the attribute android:background="?android:attr/selectableItemBackground" in the XML, but even doesn't work. I want a way of do it work in any version with just a code (without have to do separate codes for 21 version and pre 21 version). Is there a way of do this? Anyone knows how?
Thanks
The deal is that Material Design is a design language, a concept used by designers to prepare consistent UI/UX. It's not 100% implemented anywhere.
Android Lollipop has implementation of things which can be helpful in creating Material Design - compilant apps. These include shadows and ripples. Lollipop doesn't have high level Material Design things, like Floating Action Button, Snackbar, floating TextView labels and others. These are available as part of Design Support Library. You can create them by yourself as well.
Both shadows and ripples can be implemented on older Android versions to some extent. For example it's possible to create an animated ripple drawable, use it as a button's background and make it react to touch events. It's not possible to make it work smoothly, because that would require running the animation and rendering in a background thread which is available only on Lollipop and Marshmallow. Another examples are the circular reveal, the elevation system (not shadows, the drawing order) and truly rounded corners of CardView.
Colored/translucent status bar is an example of a thing which is totally reserved for Lollipop and Marshmallow, because it's a part of the system and cannot be backported at all. Another example is the new transition system.
Some things are not supported even on Lollipop. For example a floating EditText's selection toolbar. It's available only on Marshmallow. SVG graphics is not 100% supported on any Android version. Vector graphics on Lollipop and Marshmallow is a kind-of-an-SVG implementation with support for popular tags and settings. If you wish to have good vector graphics in your app, it's better to use a third party SVG reader and renderer.
ViewCompat and AppCompat make things compile. It doesn't mean that these things will work and look like on Lollipop. Design Support Library adds widgets, but most of them doesn't work like they should on Lollipop. For example CardView doesn't really cut corners, shadows are drawn with gradients, states aren't really animated. The two things you mentioned are implemented like this (pseudocode):
ViewCompat.setElevation(view, value){
if(Lollipop)
view.setElevation(value);
else
// do nothing
}
and
selectableItemBackground = Lollipop ? new RippleDrawable() : grayColor
There's a bunch of Material Design implementations scattered over github. Some of them implement only one thing, like RippleDrawable or FAB. Other libraries provide quite complete suport for widgets, shadows, etc.
Google is working on Design Support library adding more and more widgets. It doesn't have ripples or shadows yet though and probably won't have them due to performance and architectural difficulties.
I have my own library as well. I was fascinated by Material Design and frustrated by lack of implementation, so I started working on my own implementation of shadows, ripples, animations, widgets and other things. It's open source, free to use and you can find it here: https://github.com/ZieIony/Carbon
Edit: RippleDrawable
You need a RippleDrawable implementation. That should be easy as the source is open. My implementation is here: https://github.com/ZieIony/Carbon/blob/master/carbon/src/main/java/carbon/drawable/RippleDrawableFroyo.java
Then create an instance with your color and style. Set it as background.
Run RippleDrawable's animation in onTouchEvent of your view.
It's much more complicated to prepare a complete ripple with borderless mode, multiple ripples, layers, drawable states and all the stuff. If you wish, you can find all of those in Carbon (except multiple ripples). It's not only xml, but also overriden methods, extended widgets, layouts, attributes and styles.
There are simple implementations of ripples on github. If it's enough for you, you can just download a library and use it. For example this one: https://github.com/balysv/material-ripple
If you'd like to use ripples inflated from xml, it's possible as well. Check out this library: https://github.com/ozodrukh/RippleDrawable
I need to know what actual difference between TextView and TextViewCompat.
When we should use TextViewCompat?
In much the same way as other compatibility classes, it exists to provide backwards compatibility for new functions to older versions of Android.
If you compare the two, you will see the difference.
One such example is getMaxLines(). In an ordinary TextView, this requires SDK level 16. TextViewCompat introduces such functions for SDK levels from 4.
define TextViewCompat in developer.android
A TextView which supports compatible features on older version of the platform, including:
Supports textAllCaps style attribute which works back to Gingerbread.
Allows dynamic tint of it background via the background tint methods in ViewCompat.
Allows setting of the background tint using backgroundTint and backgroundTintMode.
I've seen the android developers blog that the new design support library 23.2 supports animated vector. When i searched i came across this link to implement animated vector drawable. Is it the same way to implement animated vector drawables in design support library 23.2? Can someone help me out with the new implementation?
Here's a link to an example project on Github implementing the Support Library to make this Floating Action Button.
Using the Support Library is very similar to the non-Support Library method in that the xml files for AnimatedVectorDrawables are the same, as are the objectAnimators and static VectorDrawables.
The differences come when setting up your project to use the Support Library and when referring to the AnimatedVectorDrawables in your code.
Make sure you are using at least version 23.2.0 of AppCompat in your build.gradle, the VectorDrawable and AnimatedVectorDrawable libraries do not need to be added separately:
dependencies {
...
...
compile 'com.android.support:appcompat-v7:23.2.0'
}
The official anouncement blog you linked to gives a couple of different ways to ensure Android Studio does not convert your Vector Drawables into pngs. There are two different methods depending on what version of the Gradle plugin you are using, so you should follow the appropriate one.
To call up an Animated Vector from resources in your code:
AnimatedVectorDrawableCompat animatedVector = AnimatedVectorDrawableCompat.create(this, R.drawable.animated_vector_name);
You can display this on ImageViews, Buttons etc. with their .setImageDrawable(animatedVector); method, and start the animation using animatedVector.start();
Important note: as mentioned in Chris Banes' post, there are some limitations to what will work in the support library. The sqisland.com post you linked to includes examples of Path Morphing, which won't work with the current support library(version 23.2.0)
At API Level 11 Android has started support new selector attribute, android:exitFadeDuration.
This attribute allows you to change the states with smooth animation between them.
Is there a way to stimulate the effect of this attribute on old Androids? For example, via writing custom Drawable or using Drawable transitions.