Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature: Added support for background drawables #42

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a5719b0
Library: Added background drawable support
Aug 27, 2020
8257d29
Sample: Added background drawable examples
Aug 27, 2020
5df7ef4
Merge pull request #1 from tamimattafi/dev
tamimattafi Aug 28, 2020
17bc908
Library: Fix #41 - setBackgroundDrawable called before shapeDrawable …
tamimattafi Aug 28, 2020
6be1002
Merge branch 'master' of https://github.com/fornewid/neumorphism
tamimattafi Aug 28, 2020
ca9c881
Library: Fixed app crashing when initializing a component that is bas…
tamimattafi Aug 28, 2020
a066254
Library: Code refactoring
tamimattafi Aug 28, 2020
e1d287d
Library: added reusability for shadow and background drawables
tamimattafi Jan 22, 2021
106a526
Optimizations: Made reusable bitmaps and shapes references softly rea…
Feb 20, 2021
cfcdbc2
Project: Updated target api version, updated kotlin and gradle wrappe…
Feb 20, 2021
0954522
Optimization: Changed rect hash code calculation to depend on width a…
Feb 20, 2021
8d045ae
fix: Added max cache size, removed bitmap cache
Nov 12, 2021
d866bac
feat: Add button click animation (partially)
Nov 12, 2021
cc2c2dd
update: Upgrade dependecies versions
Nov 24, 2021
42b18ad
config: Downgrade kotlin and gradle versions
Nov 24, 2021
a923580
feat: Create shadow drawable
Feb 4, 2022
c2c1d82
fix: Correct press animation
Feb 4, 2022
db5a05f
Merge pull request #2 from tamimattafi/feat/press_animation
tamimattafi Feb 4, 2022
d834ffd
fix: Remove inset, adjust pressed shape shadows
Feb 5, 2022
61434c8
fix: Correct flat shape shadow
Feb 5, 2022
2b43c88
fix: Add oval shadow coverage
Feb 6, 2022
a392fca
fix: Merge light and dark shadow in one drawable
Feb 7, 2022
9c9775c
fix: Combine light and dark shadows in one bitmap
Feb 8, 2022
ee4b3ff
fix: Correct radius and elevation
Feb 8, 2022
4cbddce
fix: Use arcs to draw shadow
Feb 8, 2022
b21aad3
fix: Correct outer shadow appearance
Feb 8, 2022
67180ad
fix: Add new shadow drawable
Feb 9, 2022
090659f
fix: Inner and outer shadow elevation
Feb 9, 2022
7236b99
fix: Use blur paint instead of rs and stack
Feb 9, 2022
b918a23
fix: Correct inner shadow
Feb 9, 2022
07c3106
fix: Fixed bitmap caching
Feb 10, 2022
1a8d79d
fix: Add simple press animation
Feb 10, 2022
5597bc8
feat: Add radius attribute to xml
Feb 10, 2022
4f3f9a4
Merge pull request #3 from tamimattafi/fix/shadow_elevation
tamimattafi Feb 10, 2022
e7b6f91
feat: Add flat press animation
Feb 10, 2022
bfd73b6
fix: add basin press animation
Feb 10, 2022
33fcaf8
feat: Add support for shape drawable
Feb 10, 2022
189ffa6
Merge pull request #4 from tamimattafi/feat/click_animation
tamimattafi Feb 10, 2022
605e9cc
fix: Crash when setting drawable state from xml
Feb 10, 2022
700907a
update: Migrate to material components
Feb 10, 2022
a288797
fix: Oval shape is sharp for rectangles
Feb 10, 2022
2d8519c
refactor: Use LruCache for caching bitmaps, use 1/6 of available VM m…
Feb 11, 2022
f0c6f56
refactor: Add possibility to configure cache size
Feb 11, 2022
9dbaced
fix: Optimize basin shape
Feb 11, 2022
349c266
fix: put a low cache size instead of dynamic one
Apr 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: Fixed bitmap caching
  • Loading branch information
Tamim Attafi authored and Tamim Attafi committed Feb 10, 2022
commit 07c3106a0376705c2d96d20e2c39a00add5ceb61
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
}
}

Expand Down
10 changes: 6 additions & 4 deletions neumorphism/src/main/java/soup/neumorphism/NeumorphButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ open class NeumorphButton @JvmOverloads constructor(
val fillColor = a.getColorStateList(R.styleable.NeumorphButton_neumorph_backgroundColor)
val strokeColor = a.getColorStateList(R.styleable.NeumorphButton_neumorph_strokeColor)
val strokeWidth = a.getDimension(R.styleable.NeumorphButton_neumorph_strokeWidth, 0f)
val shapeType = a.getInt(R.styleable.NeumorphButton_neumorph_shapeType, ShapeType.DEFAULT)
val shapeType = a.getInt(R.styleable.NeumorphButton_neumorph_shapeType, ShapeType.FLAT.ordinal)
.let { ordinal ->
ShapeType.values()[ordinal]
}

val shadowElevation = a.getDimension(
R.styleable.NeumorphButton_neumorph_shadowElevation, 0f
Expand Down Expand Up @@ -114,12 +117,11 @@ open class NeumorphButton @JvmOverloads constructor(
return shapeDrawable.getStrokeWidth()
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
shapeDrawable.setShapeType(shapeType)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return shapeDrawable.getShapeType()
}

Expand Down
11 changes: 7 additions & 4 deletions neumorphism/src/main/java/soup/neumorphism/NeumorphCardView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ open class NeumorphCardView @JvmOverloads constructor(
val fillColor = a.getColorStateList(R.styleable.NeumorphCardView_neumorph_backgroundColor)
val strokeColor = a.getColorStateList(R.styleable.NeumorphCardView_neumorph_strokeColor)
val strokeWidth = a.getDimension(R.styleable.NeumorphCardView_neumorph_strokeWidth, 0f)
val shapeType = a.getInt(R.styleable.NeumorphCardView_neumorph_shapeType, ShapeType.DEFAULT)
val shapeType = a.getInt(R.styleable.NeumorphCardView_neumorph_shapeType, ShapeType.FLAT.ordinal)
.let { ordinal ->
ShapeType.values()[ordinal]
}

val shadowElevation = a.getDimension(
R.styleable.NeumorphCardView_neumorph_shadowElevation, 0f
).roundToInt()
Expand Down Expand Up @@ -124,12 +128,11 @@ open class NeumorphCardView @JvmOverloads constructor(
return shapeDrawable.getStrokeWidth()
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
shapeDrawable.setShapeType(shapeType)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return shapeDrawable.getShapeType()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ open class NeumorphFloatingActionButton @JvmOverloads constructor(
val fillColor = a.getColorStateList(R.styleable.NeumorphFloatingActionButton_neumorph_backgroundColor)
val strokeColor = a.getColorStateList(R.styleable.NeumorphFloatingActionButton_neumorph_strokeColor)
val strokeWidth = a.getDimension(R.styleable.NeumorphFloatingActionButton_neumorph_strokeWidth, 0f)
val shapeType =
a.getInt(R.styleable.NeumorphFloatingActionButton_neumorph_shapeType, ShapeType.DEFAULT)
val shapeType = a.getInt(R.styleable.NeumorphFloatingActionButton_neumorph_shapeType, ShapeType.FLAT.ordinal)
.let { ordinal ->
ShapeType.values()[ordinal]
}

val shadowElevation = a.getDimension(
R.styleable.NeumorphFloatingActionButton_neumorph_shadowElevation, 0f
).roundToInt()
Expand Down Expand Up @@ -113,12 +116,11 @@ open class NeumorphFloatingActionButton @JvmOverloads constructor(
return shapeDrawable.getStrokeWidth()
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
shapeDrawable.setShapeType(shapeType)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return shapeDrawable.getShapeType()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ open class NeumorphImageButton @JvmOverloads constructor(
val fillColor = a.getColorStateList(R.styleable.NeumorphImageButton_neumorph_backgroundColor)
val strokeColor = a.getColorStateList(R.styleable.NeumorphImageButton_neumorph_strokeColor)
val strokeWidth = a.getDimension(R.styleable.NeumorphImageButton_neumorph_strokeWidth, 0f)
val shapeType = a.getInt(R.styleable.NeumorphImageButton_neumorph_shapeType, ShapeType.DEFAULT)
val shapeType = a.getInt(R.styleable.NeumorphImageButton_neumorph_shapeType, ShapeType.FLAT.ordinal)
.let { ordinal ->
ShapeType.values()[ordinal]
}

val shadowElevation = a.getDimension(
R.styleable.NeumorphImageButton_neumorph_shadowElevation, 0f
).roundToInt()
Expand Down Expand Up @@ -112,12 +116,11 @@ open class NeumorphImageButton @JvmOverloads constructor(
return shapeDrawable.getStrokeWidth()
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
shapeDrawable.setShapeType(shapeType)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return shapeDrawable.getShapeType()
}

Expand Down
11 changes: 7 additions & 4 deletions neumorphism/src/main/java/soup/neumorphism/NeumorphImageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ open class NeumorphImageView @JvmOverloads constructor(
val fillColor = a.getColorStateList(R.styleable.NeumorphImageView_neumorph_backgroundColor)
val strokeColor = a.getColorStateList(R.styleable.NeumorphImageView_neumorph_strokeColor)
val strokeWidth = a.getDimension(R.styleable.NeumorphImageView_neumorph_strokeWidth, 0f)
val shapeType = a.getInt(R.styleable.NeumorphImageView_neumorph_shapeType, ShapeType.DEFAULT)
val shapeType = a.getInt(R.styleable.NeumorphImageView_neumorph_shapeType, ShapeType.FLAT.ordinal)
.let { ordinal ->
ShapeType.values()[ordinal]
}

val shadowElevation = a.getDimension(
R.styleable.NeumorphImageView_neumorph_shadowElevation, 0f
).roundToInt()
Expand Down Expand Up @@ -112,12 +116,11 @@ open class NeumorphImageView @JvmOverloads constructor(
return shapeDrawable.getStrokeWidth()
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
shapeDrawable.setShapeType(shapeType)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return shapeDrawable.getShapeType()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.util.AttributeSet
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.StyleRes
import soup.neumorphism.internal.drawable.NeumorphShadow
import soup.neumorphism.internal.shape.Shape
import soup.neumorphism.internal.shape.ShapeFactory

Expand Down Expand Up @@ -155,7 +156,7 @@ open class NeumorphShapeDrawable : Drawable {
return rectF
}

fun setShapeType(@ShapeType shapeType: Int) {
fun setShapeType(shapeType: ShapeType) {
if (drawableState.shapeType != shapeType) {
drawableState.shapeType = shapeType
updateShadowShape()
Expand All @@ -170,11 +171,27 @@ open class NeumorphShapeDrawable : Drawable {
return
}

shadow = ShapeFactory.createReusableShape(drawableState, internalBounds)
val appearance = NeumorphShadow.Style(
drawableState.shadowElevation,
drawableState.blurRadius,
drawableState.shapeAppearanceModel.getCornerFamily(),
drawableState.shapeAppearanceModel.getCornerSize()
)

val theme = NeumorphShadow.Theme(
drawableState.shadowColorLight,
drawableState.shadowColorDark
)

shadow = ShapeFactory.createReusableShape(
appearance,
theme,
drawableState.shapeType,
internalBounds
)
}

@ShapeType
fun getShapeType(): Int {
fun getShapeType(): ShapeType {
return drawableState.shapeType
}

Expand Down Expand Up @@ -280,7 +297,7 @@ open class NeumorphShapeDrawable : Drawable {
drawBackgroundBitmap(canvas)
}

shadow?.draw(canvas, outlinePath)
shadow?.draw(canvas)

if (hasStroke()) {
drawStrokeShape(canvas)
Expand Down Expand Up @@ -420,8 +437,7 @@ open class NeumorphShapeDrawable : Drawable {
var strokeColor: ColorStateList? = null,
var strokeWidth: Float = 0f,
var alpha: Int = 255,
@ShapeType
var shapeType: Int = ShapeType.DEFAULT,
var shapeType: ShapeType = ShapeType.FLAT,
var shadowElevation: Int = 0,
var blurRadius: Int = 10,
var shadowColorLight: Int = Color.WHITE,
Expand Down
18 changes: 4 additions & 14 deletions neumorphism/src/main/java/soup/neumorphism/ShapeType.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
package soup.neumorphism

import androidx.annotation.IntDef
import androidx.annotation.RestrictTo

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@IntDef(ShapeType.FLAT, ShapeType.PRESSED, ShapeType.BASIN)
@Retention(AnnotationRetention.SOURCE)
annotation class ShapeType {
companion object {
const val FLAT = 0
const val PRESSED = 1
const val BASIN = 2

const val DEFAULT = FLAT
}
enum class ShapeType {
FLAT,
PRESSED,
BASIN
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
package soup.neumorphism.internal.shape

import android.graphics.Canvas
import android.graphics.Path
import android.graphics.Rect
import soup.neumorphism.NeumorphShapeDrawable.NeumorphShapeDrawableState
import soup.neumorphism.ShapeType
import soup.neumorphism.internal.drawable.NeumorphShadow
import soup.neumorphism.internal.drawable.NeumorphShape

internal class BasinShape(drawableState: NeumorphShapeDrawableState) : Shape {
internal class BasinShape(
appearance: NeumorphShadow.Style,
theme: NeumorphShadow.Theme,
bounds: Rect,
) : Shape {

private val shadows by lazy {
val theme = NeumorphShadow.Theme(
drawableState.shadowColorLight,
drawableState.shadowColorDark
val outerShadow = ShapeFactory.createReusableShape(
appearance,
theme,
ShapeType.FLAT,
bounds
)

val style = NeumorphShadow.Style(
drawableState.shadowElevation,
drawableState.blurRadius,
drawableState.shapeAppearanceModel.getCornerFamily(),
drawableState.shapeAppearanceModel.getCornerSize()
val innerShadow = ShapeFactory.createReusableShape(
appearance,
theme,
ShapeType.PRESSED,
bounds
)

listOf(
NeumorphShape(style, theme, isOuterShadow = true),
NeumorphShape(style, theme, isOuterShadow = false)
)
}

override fun draw(canvas: Canvas, outlinePath: Path) {
shadows.forEach { it.draw(canvas, outlinePath) }
listOf(outerShadow, innerShadow)
}

override fun updateShadowBitmap(bounds: Rect) {
shadows.forEach { it.updateShadowBitmap(bounds) }
override fun draw(canvas: Canvas) {
shadows.forEach { it.draw(canvas) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package soup.neumorphism.internal.shape

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Rect
import soup.neumorphism.internal.drawable.NeumorphInnerShadow
import soup.neumorphism.internal.drawable.NeumorphOuterShadow
import soup.neumorphism.internal.drawable.NeumorphShadow

internal class NeumorphShape(
private val appearance: NeumorphShadow.Style,
private val theme: NeumorphShadow.Theme,
private val bounds: Rect,
private val isOuterShadow: Boolean
) : Shape {

private var shadowBitmap: Bitmap? = null
private val shadow: NeumorphShadow by lazy {
if (isOuterShadow) NeumorphOuterShadow(appearance, theme, bounds)
else NeumorphInnerShadow(appearance, theme, bounds)
}

override fun draw(canvas: Canvas) {
val bitmap = shadowBitmap
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0f, 0f, null)
return
}

shadowBitmap = shadow.drawToBitmap()
return draw(canvas)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ import android.graphics.Path
import android.graphics.Rect

internal interface Shape {
fun draw(canvas: Canvas, outlinePath: Path)
fun updateShadowBitmap(bounds: Rect)
fun draw(canvas: Canvas)
}
Loading