Skip to content

Commit ef558e3

Browse files
committed
Targeting API 28. Added workaround for pruned canvas save(int) method. SRC: https://developer.android.com/sdk/api_diff/28/changes/android.graphics.Canvas
1 parent 45a4604 commit ef558e3

File tree

6 files changed

+132
-2
lines changed

6 files changed

+132
-2
lines changed

library/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dependencies {
1111
}
1212

1313
android {
14-
compileSdkVersion 26
14+
compileSdkVersion 28
1515
buildToolsVersion "26.0.1"
1616
lintOptions {
1717
abortOnError false

library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import android.view.animation.AnimationUtils;
2323
import android.view.animation.Interpolator;
2424

25+
import com.sothree.slidinguppanel.canvassaveproxy.CanvasSaveProxy;
26+
import com.sothree.slidinguppanel.canvassaveproxy.CanvasSaveProxyFactory;
2527
import com.sothree.slidinguppanel.library.R;
2628

2729
import java.util.List;
@@ -218,6 +220,8 @@ public enum PanelState {
218220
private View.OnClickListener mFadeOnClickListener;
219221

220222
private final ViewDragHelper mDragHelper;
223+
private final CanvasSaveProxyFactory mCanvasSaveProxyFactory;
224+
private CanvasSaveProxy mCanvasSaveProxy;
221225

222226
/**
223227
* Stores whether or not the pane was expanded the last time it was slideable.
@@ -272,6 +276,7 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs) {
272276

273277
public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
274278
super(context, attrs, defStyle);
279+
mCanvasSaveProxyFactory = new CanvasSaveProxyFactory();
275280

276281
if (isInEditMode()) {
277282
mShadowDrawable = null;
@@ -1186,7 +1191,12 @@ private void onPanelDragged(int newTop) {
11861191
@Override
11871192
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
11881193
boolean result;
1189-
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
1194+
1195+
if(mCanvasSaveProxy == null ||!mCanvasSaveProxy.isFor(canvas)) {
1196+
mCanvasSaveProxy = mCanvasSaveProxyFactory.create(canvas);
1197+
}
1198+
1199+
final int save = mCanvasSaveProxy.save(); // canvas.save(Canvas.CLIP_SAVE_FLAG);
11901200

11911201
if (mSlideableView != null && mSlideableView != child) { // if main view
11921202
// Clip against the slider; no sense drawing what will immediately be covered,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.sothree.slidinguppanel.canvassaveproxy;
2+
3+
import android.graphics.Canvas;
4+
import android.os.Build;
5+
import android.support.annotation.RequiresApi;
6+
import android.util.Log;
7+
8+
@RequiresApi(api = Build.VERSION_CODES.P)
9+
class AndroidPCanvasSaveProxy implements CanvasSaveProxy {
10+
private static final String TAG = CanvasSaveProxy.class.getSimpleName();
11+
private final Canvas mCanvas;
12+
13+
AndroidPCanvasSaveProxy(final Canvas canvas) {
14+
Log.d(TAG, "New AndroidPCanvasSaveProxy");
15+
16+
mCanvas = canvas;
17+
}
18+
19+
@Override
20+
public int save() {
21+
return mCanvas.save();
22+
}
23+
24+
@Override
25+
public boolean isFor(final Canvas canvas) {
26+
return canvas == mCanvas;
27+
}
28+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.sothree.slidinguppanel.canvassaveproxy;
2+
3+
import android.graphics.Canvas;
4+
5+
public interface CanvasSaveProxy {
6+
int save();
7+
8+
boolean isFor(final Canvas canvas);
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.sothree.slidinguppanel.canvassaveproxy;
2+
3+
import android.graphics.Canvas;
4+
import android.os.Build;
5+
6+
public class CanvasSaveProxyFactory {
7+
8+
public CanvasSaveProxy create(final Canvas canvas) {
9+
10+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
11+
return new AndroidPCanvasSaveProxy(canvas);
12+
} else {
13+
return new LegacyCanvasSaveProxy(canvas);
14+
}
15+
}
16+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.sothree.slidinguppanel.canvassaveproxy;
2+
3+
import android.graphics.Canvas;
4+
import android.util.Log;
5+
6+
import java.lang.reflect.Field;
7+
import java.lang.reflect.InvocationTargetException;
8+
import java.lang.reflect.Method;
9+
10+
@Deprecated
11+
class LegacyCanvasSaveProxy implements CanvasSaveProxy {
12+
private static final String TAG = CanvasSaveProxy.class.getSimpleName();
13+
private static final String METHOD_NAME = "save";
14+
private static final String FIELD_NAME = "CLIP_SAVE_FLAG";
15+
16+
private final Canvas mCanvas;
17+
private final Method mSaveMethod;
18+
private final int mClipSaveFlag;
19+
20+
LegacyCanvasSaveProxy(final Canvas canvas) {
21+
Log.d(TAG, "New LegacyCanvasSaveProxy");
22+
23+
mCanvas = canvas;
24+
mSaveMethod = findSaveMethod();
25+
mClipSaveFlag = getClipSaveFlagValue();
26+
}
27+
28+
@Override
29+
public int save() {
30+
return invokeSave();
31+
}
32+
33+
@Override
34+
public boolean isFor(final Canvas canvas) {
35+
return canvas == mCanvas;
36+
}
37+
38+
private int getClipSaveFlagValue() {
39+
final Field constantField;
40+
try {
41+
constantField = Canvas.class.getDeclaredField(FIELD_NAME);
42+
return (int) constantField.get(null);
43+
} catch (NoSuchFieldException e) {
44+
throw new IllegalStateException("Failed to get value of " + FIELD_NAME + " - NoSuchFieldException", e);
45+
} catch (IllegalAccessException e) {
46+
throw new IllegalStateException("Failed to get value of " + FIELD_NAME + " - IllegalAccessException", e);
47+
}
48+
}
49+
50+
private Method findSaveMethod() {
51+
try {
52+
return Canvas.class.getMethod(METHOD_NAME, int.class);
53+
} catch (NoSuchMethodException e) {
54+
throw new IllegalStateException("Canvas does not contain a method with signature save(int)");
55+
}
56+
}
57+
58+
private int invokeSave() {
59+
try {
60+
return (int) mSaveMethod.invoke(mCanvas, mClipSaveFlag);
61+
} catch (IllegalAccessException e) {
62+
throw new IllegalStateException("Failed to execute save(int) - IllegalAccessException", e);
63+
} catch (InvocationTargetException e) {
64+
throw new IllegalStateException("Failed to execute save(int) - InvocationTargetException", e);
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)