I'm working on an Android TV application but I'm not quite happy with the standard shadow rendered by the VerticalGridFragment, I'd like to have it smaller and a bit less darker.
I've searched through the code but I didn't find any full working solution.
In my VerticalGridPresenter subclass, the only method I can override is createShadowOverlayOptions but I can't get the result I want.
The only workaround I came up with is to define the following dimensions, so that the ones declared in the Support Library are overridden:
<dimen name="lb_material_shadow_details_z">3dp</dimen>
<dimen name="lb_material_shadow_focused_z">4dp</dimen>
<dimen name="lb_material_shadow_normal_z">3dp</dimen>
But it's more an hack rather than a proper solution.
This is the standard shadow:
This is the result I get with my current hack:
As you can I see, it's smaller but I cannot change the color.
Is there a proper way to set shadow color and dimension for VerticalGridFragment and RowsFragment classes?
I'm using latest Leanback version:
compile 'com.android.support:leanback-v17:25.2.0'
My minSdkVersion is 17 because of a custom Android TV player, but it's fine to have it working starting from 21.
I've actually asked the Leanback team about this before and they said the recommended way of customizing their components is through overriding the styles and dimens. So that might help assuage some of your worry.
However, we also had to customize the shadows on our views. We did this by creating our own views and our own view presenters (instead of using their ImageCardView). With that we were able to set our own shadows at the presentation level.
If you look at the documentation for ListRowPresenter the docs say:
ListRowPresenter applies a default shadow to each child view. Call setShadowEnabled(boolean) to disable shadows. A subclass may override and return false in isUsingDefaultShadow() and replace with its own shadow implementation.
To see more of how they handle shadows, please look into the source code of ListRowPresenter and also check out the ShadowHelper and ShadowHelperApi21 classes to see how they've implemented adding shadows to their list items. We actually just copied over those two classes since they are package-local.
You can also override ShadowOverlayHelper.Options createShadowOverlayOptions() in ListRowPresenter which gives you some ability to change corner radius and focused and unfocused z.
Related
We have an imageView whose background has a vector asset drawable(ic_star.xml). When I change the background tint of this imageView programatically with a custom color like below, it causes to change the color of imageViews on other pages using this vector assset. In other words, whatever color I set last, that color stays on all other screens. I think this function directly affects the vector asset used throughout the application.
binding.imageView.background.setTint(Color.parseColor("#0E8E1D"))}
In addition, when I use android:backgroundTint attribute in XML, this problem does not occur. Other pages are not affected. But since I get the colors from the api, I have to do it programmatically. We do not prefer to use databinding in our project as it increases the build time. That's why I can't handle this with binding expression.
I found a solution when I wanted to look at the effect of the imageView.background.setTint(color : Int) function in a simple app. I wasn't too sure if it was the right solution. backgroundTintList property worked like android:backgroundTint attribute in xml.
binding.imageView.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#0E8E1D"))
You can review my example app in github and try the difference imageView.backgroundTintList and imageView.background.setTint() methods. I'm waiting for your comments.
https://github.com/tugceaktepe/ImageViewTint
Thanks.
I did a materalistic designed "Add" button on my Android-primary react-native app. While I used elevation style property as a primary source for shadows in the rest of the elements, I've discovered that it stops working when applied to an absolute positioned element. (Which I partially understand probably because absolutely positioned element ignores the general layout rules, but still, a shadow should work).
As far as I know, Android gets elevation and iOS gets their respective shadow properties.
I'd like to have this:
but I 'm getting no shadow once I set the element's style as absolute (in the bottom right corner).
Am I missing something or is it not working yet?
Simply, there is no current shadow support for Android in React Native yet and I think you are on the right track to use elevation way to achieve this. But it should only work for Android 5.0 or above.
Alternatively, you can try this module (https://github.com/879479119/react-native-shadow). It works for me.
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
What is the difference between an AppCompat view component and a standard/default view component?
For example, the difference between an AppCompatEditText, and an EditText, or between an AppCompatButton and a Button.
Looking at the developer docs for android.support.v7.widget, the AppCompat view components are described as "tint aware", but is this the only difference, and what exactly does this do?
When you are using a Button or an EditText you are actually using AppCompatButton and AppCompatEditText. From the official documentation of the AppCompatEditText.
A tint aware EditText. This will automatically be used when you use EditText in your layouts. You should only need to manually use this class when writing custom views
What is the difference between an AppCompat view component and a
standard/default view component?
AppCompat View Component supports compatible features on older version of the platform.
the AppCompat view components are described as "tint aware", but is
this the only difference, and what exactly does this do?
Although most of the AppCompatView only difference is it allows dynamic tint and background tint. Tint aware is not the only difference, each AppCompatView has its own differences, for example.
AppCompatEditText vs EditText
Allows textAllCaps style attribute up to Gingerbread.
AppCompatSpinner vs Spinner
Setting the popup theme using popupTheme.
You can dig down each view difference in Android docs.
However, as Sid / Docs says, you don't have to specify this on your layouts since it will automatically converted to AppCompat views. But, if you want to create custom view, you should use AppCompat Views, or else this bug will happens.
well one of differences that i have noticed , in order to change the background of a normal Button , you have to modify the XML ( to NoActionBar..
android:theme="#style/Theme.AppCompat.Light.NoActionBar" to
android:theme="#style/Theme.MaterialComponents.DayNight.NoActionBar"
whatever all i want to say is it difficult to work with buttons than the AppCompat version ).
so the use of androidx.appcompat.widget.AppCompatButton is somehow considered good because you will avoid a lot of little problems using the androidx library.
There are lots of way to style ListViews to give them elegant look, but all of them involve modyfying the adapter or writing additional code.
With the release of Android 4.0, unfortunetely things have to change. Google polished their Holo theme and gave it new look. All of the developers are now encouraged to use it, in order to make all apps look the same.
And here's the problem. Google rolled out 4.0, but there are still people using older Android versions. We can't just leave our previous custom application themes and use Holo, because it will ruin visual experience for users with older devices. And we can't force 4.0 users just to use Holo, because let's be honest - it's still not perfect.
The goal is to use builtin themes system and prepare some alternatives for Holo, which will look great on all devices. Then we can just switch between Holo and our themes with just setTheme() and no additional problems. Unfortunetely it's not that simple. We are limited to the capabilities of existing theme system and some things are just hard to do. And here comes my question.
Taking everything I've mentioned into consideration, how can we control ListView look? I'm not able to figure out, how to:
create list with rounded corners and make sure the selector background doesn't ruin it when selecting first/last element
create rounded corners not for the list but sections separated by headers, something like here:
The solution should affect ListViews created by PreferenceActivity without any additional lines of code. Everything should be contained in the theme:
<theme name="SampleTheme" parent="android:Theme">
...
</theme>
I kindly ask not to post solutions that do not use styles & themes. They can be easily found in another questions, here on Stack Overflow.
Thanks in advance.
I can see two ways to solve this.
One is simply to use a theme for your listviews specifying the background, which in turn is a 9 patch with rounded corners or an xml shape you specify (with rounded corners as well). This will have the side-effect of the listview row selector appearing 'over' the background you specified, therefore kind of spoiling the effect. It is quite straightforward to implement though.
The second option is to simply always add headers and footers to your listviews, which have backgrounds that are selectors with rounded corners on top (and bottom). You can specify styles for these as well if you really want to.
Sorry for this last comment, but I had to say it. Please don't try to make your app look like an iPhone app :)