|
31 | 31 | import android.graphics.Rect;
|
32 | 32 | import android.os.Build.VERSION;
|
33 | 33 | import android.os.Build.VERSION_CODES;
|
| 34 | +import android.util.DisplayMetrics; |
34 | 35 | import android.view.RoundedCorner;
|
35 | 36 | import android.view.View;
|
36 | 37 | import android.view.WindowInsets;
|
@@ -61,7 +62,7 @@ public class MaterialMainContainerBackHelper extends MaterialBackAnimationHelper
|
61 | 62 | private float initialTouchY;
|
62 | 63 | @Nullable private Rect initialHideToClipBounds;
|
63 | 64 | @Nullable private Rect initialHideFromClipBounds;
|
64 |
| - @Nullable private Integer expandedCornerSize; |
| 65 | + @Nullable private float[] expandedCornerRadii; |
65 | 66 |
|
66 | 67 | public MaterialMainContainerBackHelper(@NonNull View view) {
|
67 | 68 | super(view);
|
@@ -141,7 +142,8 @@ public void updateBackProgress(
|
141 | 142 | view.setTranslationY(translationY);
|
142 | 143 | if (view instanceof ClippableRoundedCornerLayout) {
|
143 | 144 | ((ClippableRoundedCornerLayout) view)
|
144 |
| - .updateCornerRadius(lerp(getExpandedCornerSize(), collapsedCornerSize, progress)); |
| 145 | + .updateCornerRadii( |
| 146 | + lerpCornerRadii(getExpandedCornerRadii(), collapsedCornerSize, progress)); |
145 | 147 | }
|
146 | 148 | }
|
147 | 149 |
|
@@ -198,41 +200,92 @@ public void onAnimationEnd(Animator animation) {
|
198 | 200 | private ValueAnimator createCornerAnimator(
|
199 | 201 | ClippableRoundedCornerLayout clippableRoundedCornerLayout) {
|
200 | 202 | ValueAnimator cornerAnimator =
|
201 |
| - ValueAnimator.ofFloat( |
202 |
| - clippableRoundedCornerLayout.getCornerRadius(), getExpandedCornerSize()); |
| 203 | + ValueAnimator.ofObject( |
| 204 | + (fraction, startValue, endValue) -> |
| 205 | + lerpCornerRadii((float[]) startValue, (float[]) endValue, fraction), |
| 206 | + clippableRoundedCornerLayout.getCornerRadii(), |
| 207 | + getExpandedCornerRadii()); |
203 | 208 | cornerAnimator.addUpdateListener(
|
204 | 209 | animation ->
|
205 |
| - clippableRoundedCornerLayout.updateCornerRadius((Float) animation.getAnimatedValue())); |
| 210 | + clippableRoundedCornerLayout.updateCornerRadii((float[]) animation.getAnimatedValue())); |
206 | 211 | return cornerAnimator;
|
207 | 212 | }
|
208 | 213 |
|
209 |
| - public int getExpandedCornerSize() { |
210 |
| - if (expandedCornerSize == null) { |
211 |
| - expandedCornerSize = isAtTopOfScreen() ? getMaxDeviceCornerRadius() : 0; |
| 214 | + private static float[] lerpCornerRadii(float[] startValue, float[] endValue, float fraction) { |
| 215 | + return new float[] { |
| 216 | + lerp(startValue[0], endValue[0], fraction), |
| 217 | + lerp(startValue[1], endValue[1], fraction), |
| 218 | + lerp(startValue[2], endValue[2], fraction), |
| 219 | + lerp(startValue[3], endValue[3], fraction), |
| 220 | + lerp(startValue[4], endValue[4], fraction), |
| 221 | + lerp(startValue[5], endValue[5], fraction), |
| 222 | + lerp(startValue[6], endValue[6], fraction), |
| 223 | + lerp(startValue[7], endValue[7], fraction) |
| 224 | + }; |
| 225 | + } |
| 226 | + |
| 227 | + private static float[] lerpCornerRadii(float[] startValue, float endValue, float fraction) { |
| 228 | + return new float[] { |
| 229 | + lerp(startValue[0], endValue, fraction), |
| 230 | + lerp(startValue[1], endValue, fraction), |
| 231 | + lerp(startValue[2], endValue, fraction), |
| 232 | + lerp(startValue[3], endValue, fraction), |
| 233 | + lerp(startValue[4], endValue, fraction), |
| 234 | + lerp(startValue[5], endValue, fraction), |
| 235 | + lerp(startValue[6], endValue, fraction), |
| 236 | + lerp(startValue[7], endValue, fraction) |
| 237 | + }; |
| 238 | + } |
| 239 | + |
| 240 | + @NonNull |
| 241 | + public float[] getExpandedCornerRadii() { |
| 242 | + if (expandedCornerRadii == null) { |
| 243 | + expandedCornerRadii = calculateExpandedCornerRadii(); |
212 | 244 | }
|
213 |
| - return expandedCornerSize; |
| 245 | + return expandedCornerRadii; |
214 | 246 | }
|
215 | 247 |
|
216 |
| - private boolean isAtTopOfScreen() { |
217 |
| - int[] location = new int[2]; |
218 |
| - view.getLocationOnScreen(location); |
219 |
| - return location[1] == 0; |
| 248 | + public void clearExpandedCornerRadii() { |
| 249 | + expandedCornerRadii = null; |
220 | 250 | }
|
221 | 251 |
|
222 |
| - private int getMaxDeviceCornerRadius() { |
| 252 | + private float[] calculateExpandedCornerRadii() { |
223 | 253 | if (VERSION.SDK_INT >= VERSION_CODES.S) {
|
224 | 254 | final WindowInsets insets = view.getRootWindowInsets();
|
225 | 255 | if (insets != null) {
|
226 |
| - return max( |
227 |
| - max( |
228 |
| - getRoundedCornerRadius(insets, RoundedCorner.POSITION_TOP_LEFT), |
229 |
| - getRoundedCornerRadius(insets, RoundedCorner.POSITION_TOP_RIGHT)), |
230 |
| - max( |
231 |
| - getRoundedCornerRadius(insets, RoundedCorner.POSITION_BOTTOM_LEFT), |
232 |
| - getRoundedCornerRadius(insets, RoundedCorner.POSITION_BOTTOM_RIGHT))); |
| 256 | + DisplayMetrics displayMetrics = view.getResources().getDisplayMetrics(); |
| 257 | + int screenWidth = displayMetrics.widthPixels; |
| 258 | + int screenHeight = displayMetrics.heightPixels; |
| 259 | + |
| 260 | + int[] location = new int[2]; |
| 261 | + view.getLocationOnScreen(location); |
| 262 | + int x = location[0]; |
| 263 | + int y = location[1]; |
| 264 | + |
| 265 | + int width = view.getWidth(); |
| 266 | + int height = view.getHeight(); |
| 267 | + |
| 268 | + int topLeft = |
| 269 | + x == 0 && y == 0 ? getRoundedCornerRadius(insets, RoundedCorner.POSITION_TOP_LEFT) : 0; |
| 270 | + int topRight = |
| 271 | + x + width >= screenWidth && y == 0 |
| 272 | + ? getRoundedCornerRadius(insets, RoundedCorner.POSITION_TOP_RIGHT) |
| 273 | + : 0; |
| 274 | + int bottomRight = |
| 275 | + x + width >= screenWidth && y + height >= screenHeight |
| 276 | + ? getRoundedCornerRadius(insets, RoundedCorner.POSITION_BOTTOM_RIGHT) |
| 277 | + : 0; |
| 278 | + int bottomLeft = |
| 279 | + x == 0 && y + height >= screenHeight |
| 280 | + ? getRoundedCornerRadius(insets, RoundedCorner.POSITION_BOTTOM_LEFT) |
| 281 | + : 0; |
| 282 | + |
| 283 | + return new float[] { |
| 284 | + topLeft, topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft |
| 285 | + }; |
233 | 286 | }
|
234 | 287 | }
|
235 |
| - return 0; |
| 288 | + return new float[] {0, 0, 0, 0, 0, 0, 0, 0}; |
236 | 289 | }
|
237 | 290 |
|
238 | 291 | @RequiresApi(VERSION_CODES.S)
|
|
0 commit comments