CSS-style shadows for Android

Related tags

GUI FiftyShades
Overview

Fifty Shades: CSS-style shadows for Android

What?

In CSS, shadows are specified by (dx, dy, blurRadius, colour) (I call it ShadowSpec). This library implements such shadows for Android.

Why?

I know only two shadow implementations in Android SDK out of the box: Paint#setShadowLayer and View#elevation.

ShadowLayer produces nice-looking shadows but works only with software rendering. A sheet with shadow could be big, containing many pixels, but this becomes even worse if you set SOFTWARE_LAYER on a whole full-screen RecyclerView in order to draw background properly.

Elevation is implemented somewhere deep inside RenderNode, there's no direct control over this shadow, there's no such a thing like Canvas#drawElevation. Also, speaking in terms of CSS, dx=0, and both dy and blurRadius are driven by elevation. Elevation colour is one more pain in the ass, but, well, I think you already know it.

There's also MaterialShapeDrawable which is actually a poor man's elevation. Same problems as above apply plus drawing artifacts. It also drops shadowColor's alpha; Drawable#setAlpha invocations don't alter shadow transparency either.

How?

repositories {
    // Groovy:
    maven { url 'https://jitpack.io' }
    
    // Kotlin:
    maven(url = "https://jitpack.io")
}

// module-level build.gradle:
dependencies {
    implementation('com.github.Miha-x64:FiftyShades:-SNAPSHOT')
}

Static shadow

RectWithShadow.createDrawable(
    RectSpec(Color.WHITE, dp(20)),
    ShadowSpec(dp(2), dp(3), dp(20), Color.BLACK)
)

This will return a Drawable (a NinePatchDrawable wrapped in InsetDrawable, actually) with a white rectangle, round corners (20dp radius), and a black shadow blurred by 20dp and offset by (2dp; 3dp).

Keep in mind that it will draw out of bounds, so clipChildren=false on parent layout is required.

Dynamic shadow

LayerDrawable(arrayOf(
    RectShadow(dp(20), ShadowSpec(dp(2), dp(3), dp(20), Color.BLACK)),
    RoundRectDrawable(Color.WHITE, dp(20)) // explained later
))

RectShadow draws a shadow (out of bounds, remember!) while RoundRectDrawable, well, it draws a round rect.

Now you can modify properties of RectShadow at runtime: .cornerRadius(100500).shadow(nicerShadow)

Inner shadow

LayerDrawable(arrayOf(
    RoundRectDrawable(Color.WHITE, dp(20)), // explained later
    RectInnerShadow(dp(20), ShadowSpec(dp(2), dp(3), dp(20), Color.BLACK))
))

Add Inner, make it draw after round rect, and that's it: inner shadow, known as inset in CSS. Interface is the same.

Dafuq is RoundRectDrawable?

It's just standard GradientDrawable (a.k.a. <shape>):

fun RoundRectDrawable(@ColorInt color: Int, @Px radius: Int): Drawable =
    GradientDrawable().apply {
        setColor(color)
        setCornerRadius(radius)
    }

ItemDecoration for RecyclerView

You may want to create a RecyclerView, set clipChildren=false, and set drawables with shadow as item backgrounds. This will work 99% of time but fail miserably during item animations: when alpha < 1, clipChildren becomes effectively true because of intermediate buffer which has its bounds, so you will have your shadows clipped.

The saviour is RectItemsWithShadows(rect, shadow) item decorator with an already familiar constructor. Individual item properties are controllable and animatable:

itemView.stateListAnimator = StateListAnimator().apply {
    addState(intArrayOf(android.R.attr.state_selected),
        ObjectAnimator.ofPropertyValuesHolder(null as Any?,
            PropertyValuesHolder.ofFloat(DECOR_SHADOW_RADIUS, dp(32f)),
            PropertyValuesHolder.ofInt(DECOR_SHADOW_COLOR, 0xFF_AAFFCC.toInt()).argb(),
            PropertyValuesHolder.ofInt(DECOR_RECT_FILL_COLOR, 0xFF_AAFFCC.toInt()).argb(),
        )
    )
    addState(intArrayOf(),
        ObjectAnimator.ofPropertyValuesHolder(null as Any?,
            PropertyValuesHolder.ofFloat(DECOR_SHADOW_RADIUS, dp(8f)),
            PropertyValuesHolder.ofInt(DECOR_SHADOW_COLOR, 0x66_000000).argb(),
            PropertyValuesHolder.ofInt(DECOR_RECT_FILL_COLOR, Color.WHITE).argb(),
        )
    )
}

private val argbEvaluator = ArgbEvaluator()
fun PropertyValuesHolder.argb(): PropertyValuesHolder = apply { setEvaluator(argbEvaluator) }

Some shadows

You might also like...

Ini adalah Launcher SAMP untuk android, ini hanya untuk mengganti nama dan kemungkinan di update lanjutnya akan mendukung download client. Bersenang senanglah!!!

SAMP-Launcher-Android Ini adalah Launcher SAMP untuk android, ini hanya untuk mengganti nama dan kemungkinan di update lanjutnya akan mendukung downlo

Nov 3, 2022

An Android library that allows you to easily create applications with slide-in menus.

An Android library that allows you to easily create applications with slide-in menus. You may use it in your Android apps provided that you cite this project and include the license in your app. Thanks!

Jan 4, 2023

Implementation of ImageView for Android that supports zooming, by various touch gestures.

Implementation of ImageView for Android that supports zooming, by various touch gestures.

PhotoView PhotoView aims to help produce an easily usable implementation of a zooming Android ImageView. [ Dependency Add this in your root build.grad

Dec 30, 2022

RxJava bindings for Android

RxAndroid: Reactive Extensions for Android Android specific bindings for RxJava 3. This module adds the minimum classes to RxJava that make writing re

Dec 28, 2022

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.

⚡ A powerful & easy to use chart library for Android ⚡ Charts is the iOS version of this library Table of Contents Quick Start Gradle Maven Documentat

Jan 9, 2023

CSS keyframe animation for JavaFX. Create animations like you would do with CSS.

CSS keyframe animation for JavaFX. Create animations like you would do with CSS.

JFXAnimation CSS keyframe animation for JavaFX. If you are using JFoenix JFXAnimation is included (currently version 1.0.0 only) Requirements JDK 8 an

Dec 28, 2022

Android Auto Apps Downloader (AAAD) is an app for Android Phones that downloads popular Android Auto 3rd party apps and installs them in the correct way to have them in Android Auto.

Android Auto Apps Downloader (AAAD) is an app for Android Phones that downloads popular Android Auto 3rd party apps and installs them in the correct way to have them in Android Auto.

Android Auto Apps Downloader (AAAD) is an app for Android Phones that downloads popular Android Auto 3rd party apps and installs them in the correct way to have them in Android Auto.

Jan 2, 2023

XML/XHTML and CSS 2.1 renderer in pure Java

Flying Saucer OVERVIEW Flying Saucer is a pure-Java library for rendering arbitrary well-formed XML (or XHTML) using CSS 2.1 for layout and formatting

Jan 2, 2023

Allow runtime modification of JavaFX CSS

Allow runtime modification of JavaFX CSS

cssfx ⚠ WARNING ⚠ In version 11.3.0 we have relocated & refactored the project. maven groupId has been changed to fr.brouillard.oss java module name h

Jan 2, 2023

Nokogiri (鋸) is a Rubygem providing HTML, XML, SAX, and Reader parsers with XPath and CSS selector support.

Nokogiri Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby. It provides a sensible, easy-to-understand API for reading, writ

Jan 8, 2023

These samples explore the different options that Spring Boot developers have for using Javascript and CSS on the client (browser) side of their application.

These samples explore the different options that Spring Boot developers have for using Javascript and CSS on the client (browser) side of their application.

Table of Contents Getting Started Narrowing the Choices Create a New Application Webjars Show Me Some Javascript Normalizing Resource Paths Adding Tab

Jul 29, 2022

Student management system with sql database,Jsp & Java (Front end with HTML & CSS)

studentmanagementsystem Student management system with sql database,Jsp & Java (Front end with HTML & CSS) what this basically is that it integrates t

Oct 3, 2022

LINQ-style queries for Java 8

JINQ: Easy Database Queries for Java 8 Jinq provides developers an easy and natural way to write database queries in Java. You can treat database data

Dec 28, 2022

Library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine.

J8Spec J8Spec is a library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine. More details here: j8spec.github

Feb 17, 2022

An MIT AI2 extension to allows developers to show media style notifications for their applications.

An MIT AI2 extension to allows developers to show media style notifications for their applications.

Media Notifications An MIT AI2 extension to allows developers to show media style notifications for their applications.

Jan 7, 2023

A Minecraft Java mod that adds 48 pieces of functional, decorative and unique furniture that fit with the vanilla style.

A Minecraft Java mod that adds 48 pieces of functional, decorative and unique furniture that fit with the vanilla style.

FurniDeco ( 🚧 WIP) FurniDeco adds 25 pieces of functional, decorative and unique-looking furniture that fit with the vanilla style. With more than 80

Jul 3, 2022

GzKitchen - Japanese Style Restaurant (Mobile App)

GzKitchen-Android GzKitchen - Japanese Style Restaurant (Mobile App) How to copy the project to your local machine : Download / clone tihs repository

Jan 9, 2022
Owner
Mike
Remote & part-time, Android & server-side, development & consulting.
Mike
Allow runtime modification of JavaFX CSS

cssfx ⚠ WARNING ⚠ In version 11.3.0 we have relocated & refactored the project. maven groupId has been changed to fr.brouillard.oss java module name h

Matthieu Brouillard 134 Jan 2, 2023
🌄 Image editor using native modules for iOS and Android. Inherit from 2 available libraries, Brightroom (iOS) and PhotoEditor (Android)

React Native Photo Editor (RNPE) ?? Image editor using native modules for iOS and Android. Inherit from 2 available libraries, Brightroom (iOS) and Ph

Baron Ha. 243 Jan 4, 2023
Android Resource Manager application to manage and analysis your app resources with many features like image resize, Color, Dimens and code Analysis

AndroidResourceManager Cross-Platform tools to manage your resources as an Android Developer, AndroidResourceManager - ARM provide five main services

Amr Hesham 26 Nov 16, 2022
Simple, maintained and highly customizable colorpicker library for Android.

Colorpicker Library for Android Simple, maintained and highly customizable color picker library for Android. It is packed with ColorPicker Popup, Colo

Mrudul Tora 31 Oct 3, 2022
A simple implementation of the Android In-App Billing API.

Google In-App Billing Library v4+ A simple implementation of the Android In-App Billing API. It supports: in-app purchases (both consumable and non-co

Moisoni Ioan 79 Dec 12, 2022
A simple Android Tag EditText

TagEditText A simple Android Tag EditText. Setup The easiest way to add the TagEditText library to your project is by adding it as a dependency to you

HearSilent 15 May 5, 2022
A low intrusive, configurable android library that converts layout XML files into Java code to improve performance

qxml English 一个低侵入,可配置的 Android 库,用于将 layout xml 文件转换为 Java 代码以提高性能。 与X2C的对比 X2C: 使用注解处理器生成View类,使用时需要在类中添加注解,并替换setContentView方法,侵入性较强; 对于布局属性的支持不够完美

null 74 Oct 6, 2022
Lifecycle-aware shared observable data holder class for android.

Eyejet Lifecycle-aware shared observable data holder class for android. 1. Depend on our library Eyejet Library is available through Maven Repository.

ZeoFlow 16 Jul 27, 2021
An open source application to make your own android applications without coding!

Stif An Open source project for building Android Application at a go both with and without coding. This project was inspired from Scratch and Sketchwa

Nethical org 5 Aug 28, 2021
an android app to browse urls before open

link eye - kuesji koesnu - 8/8/2021 an android app to browse urls before open try to open a link, select link eye and choose always to start using

kuesji koesnu 25 Dec 31, 2022