Skip to content
This repository was archived by the owner on Nov 21, 2024. It is now read-only.

Commit e3d8ff9

Browse files
committed
Support ShapeAppearances in MaterialContainerTransition.
Change-Id: I397ef14fd8efd3aae5ab0749bdba21e249f4834b
1 parent 26fa6ee commit e3d8ff9

File tree

9 files changed

+264
-59
lines changed

9 files changed

+264
-59
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ android {
4747

4848
dependencies {
4949
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
50-
implementation 'androidx.fragment:fragment:1.2.0-alpha01'
50+
implementation 'androidx.fragment:fragment:1.2.0-alpha02'
5151
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
5252
implementation 'androidx.core:core-ktx:1.0.2'
5353
implementation 'com.google.android.material:material:1.1.0-alpha09'

app/src/main/java/com/materialstudies/owl/util/AnimationUtils.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,56 @@ fun lerp(
8787
return lerp(startValue, endValue, (fraction - startFraction) / (endFraction - startFraction))
8888
}
8989

90+
/**
91+
* Linearly interpolate between two [CornerRounding]s when the fraction is in a given range.
92+
*/
93+
fun lerp(
94+
startValue: CornerRounding,
95+
endValue: CornerRounding,
96+
@FloatRange(
97+
from = 0.0,
98+
fromInclusive = true,
99+
to = 1.0,
100+
toInclusive = false
101+
) startFraction: Float,
102+
@FloatRange(from = 0.0, fromInclusive = false, to = 1.0, toInclusive = true) endFraction: Float,
103+
@FloatRange(from = 0.0, fromInclusive = true, to = 1.0, toInclusive = true) fraction: Float
104+
): CornerRounding {
105+
if (fraction < startFraction) return startValue
106+
if (fraction > endFraction) return endValue
107+
108+
return CornerRounding(
109+
lerp(
110+
startValue.topLeftRadius,
111+
endValue.topLeftRadius,
112+
startFraction,
113+
endFraction,
114+
fraction
115+
),
116+
lerp(
117+
startValue.topRightRadius,
118+
endValue.topRightRadius,
119+
startFraction,
120+
endFraction,
121+
fraction
122+
),
123+
lerp(
124+
startValue.bottomRightRadius,
125+
endValue.bottomRightRadius,
126+
startFraction,
127+
endFraction,
128+
fraction
129+
),
130+
lerp(
131+
startValue.bottomLeftRadius,
132+
endValue.bottomLeftRadius,
133+
startFraction,
134+
endFraction,
135+
fraction
136+
)
137+
)
138+
}
139+
90140
/**
91141
* Linearly interpolate between two colors when the fraction is in a given range.
92142
*/
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.materialstudies.owl.util
18+
19+
import android.graphics.Canvas
20+
import android.graphics.Paint
21+
import android.graphics.Path
22+
import android.graphics.Rect
23+
import android.graphics.RectF
24+
import android.graphics.Shader
25+
import androidx.core.graphics.toRectF
26+
import com.google.android.material.shape.RoundedCornerTreatment
27+
import com.google.android.material.shape.ShapeAppearanceModel
28+
29+
// TODO make inline class once non-experimental
30+
class CornerRounding(
31+
val topLeftRadius: Float = 0f,
32+
val topRightRadius: Float = 0f,
33+
val bottomRightRadius: Float = 0f,
34+
val bottomLeftRadius: Float = 0f
35+
)
36+
37+
// To FloatArray suitable for Path#addRoundRect
38+
fun CornerRounding.toFloatArray(): FloatArray {
39+
return floatArrayOf(
40+
topLeftRadius, topLeftRadius,
41+
topRightRadius, topRightRadius,
42+
bottomRightRadius, bottomRightRadius,
43+
bottomLeftRadius, bottomLeftRadius
44+
)
45+
}
46+
47+
fun ShapeAppearanceModel?.toCornerRounding(): CornerRounding {
48+
if (this == null) return CornerRounding()
49+
// TODO handle non rounded corners?
50+
return CornerRounding(
51+
if (topLeftCorner is RoundedCornerTreatment) topLeftCorner.cornerSize else 0f,
52+
if (topRightCorner is RoundedCornerTreatment) topRightCorner.cornerSize else 0f,
53+
if (bottomRightCorner is RoundedCornerTreatment) bottomRightCorner.cornerSize else 0f,
54+
if (bottomLeftCorner is RoundedCornerTreatment) bottomLeftCorner.cornerSize else 0f
55+
)
56+
}
57+
58+
private val path = Path()
59+
fun Canvas.drawRoundedRect(
60+
location: RectF,
61+
cornerRadii: CornerRounding,
62+
paint: Paint
63+
) {
64+
path.apply {
65+
reset()
66+
addRoundRect(location, cornerRadii.toFloatArray(), Path.Direction.CW)
67+
}
68+
drawPath(path, paint)
69+
}

app/src/main/java/com/materialstudies/owl/util/ViewExtensions.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package com.materialstudies.owl.util
1818

1919
import android.animation.ValueAnimator
2020
import android.content.Context
21+
import android.graphics.Bitmap
22+
import android.graphics.Bitmap.Config.ARGB_8888
2123
import android.graphics.Color
2224
import android.graphics.drawable.BitmapDrawable
2325
import android.graphics.drawable.ColorDrawable
@@ -30,8 +32,11 @@ import android.view.animation.AnimationUtils
3032
import androidx.annotation.AttrRes
3133
import androidx.annotation.ColorInt
3234
import androidx.annotation.IdRes
35+
import androidx.annotation.Px
3336
import androidx.core.animation.doOnEnd
3437
import androidx.core.content.res.use
38+
import androidx.core.graphics.applyCanvas
39+
import androidx.core.view.ViewCompat
3540
import androidx.core.view.drawToBitmap
3641
import androidx.core.view.forEach
3742
import androidx.dynamicanimation.animation.DynamicAnimation.ViewProperty
@@ -242,3 +247,18 @@ fun BottomNavigationView.hide() {
242247
start()
243248
}
244249
}
250+
251+
/**
252+
* A copy of the KTX method, adding the ability to add extra padding the bottom of the [Bitmap];
253+
* useful when it will be used in a [android.graphics.BitmapShader][BitmapShader] with
254+
* a [android.graphics.Shader.TileMode.CLAMP][CLAMP tile mode].
255+
*/
256+
fun View.drawToBitmap(@Px extraPaddingBottom: Int = 0): Bitmap {
257+
if (!ViewCompat.isLaidOut(this)) {
258+
throw IllegalStateException("View needs to be laid out before calling drawToBitmap()")
259+
}
260+
return Bitmap.createBitmap(width, height + extraPaddingBottom, ARGB_8888).applyCanvas {
261+
translate(-scrollX.toFloat(), -scrollY.toFloat())
262+
draw(this)
263+
}
264+
}

0 commit comments

Comments
 (0)