Skip to content

Commit

Permalink
Targeting API 28. Added workaround for pruned canvas save(int) method…
Browse files Browse the repository at this point in the history
  • Loading branch information
alt236 committed Jul 6, 2018
1 parent 45a4604 commit 7af57e8
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 2 deletions.
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dependencies {
}

android {
compileSdkVersion 26
compileSdkVersion 28
buildToolsVersion "26.0.1"
lintOptions {
abortOnError false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

import com.sothree.slidinguppanel.canvassaveproxy.CanvasSaveProxy;
import com.sothree.slidinguppanel.canvassaveproxy.CanvasSaveProxyFactory;
import com.sothree.slidinguppanel.library.R;

import java.util.List;
Expand Down Expand Up @@ -218,6 +220,8 @@ public enum PanelState {
private View.OnClickListener mFadeOnClickListener;

private final ViewDragHelper mDragHelper;
private final CanvasSaveProxyFactory mCanvasSaveProxyFactory;
private CanvasSaveProxy mCanvasSaveProxy;

/**
* Stores whether or not the pane was expanded the last time it was slideable.
Expand Down Expand Up @@ -273,6 +277,8 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs) {
public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);

mCanvasSaveProxyFactory = new CanvasSaveProxyFactory();

if (isInEditMode()) {
mShadowDrawable = null;
mDragHelper = null;
Expand Down Expand Up @@ -1186,7 +1192,12 @@ private void onPanelDragged(int newTop) {
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result;
final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);

if (mCanvasSaveProxy == null || !mCanvasSaveProxy.isFor(canvas)) {
mCanvasSaveProxy = mCanvasSaveProxyFactory.create(canvas);
}

final int save = mCanvasSaveProxy.save();

if (mSlideableView != null && mSlideableView != child) { // if main view
// Clip against the slider; no sense drawing what will immediately be covered,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.sothree.slidinguppanel.canvassaveproxy;

import android.graphics.Canvas;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

@RequiresApi(api = Build.VERSION_CODES.P)
class AndroidPCanvasSaveProxy implements CanvasSaveProxy {
private static final String TAG = CanvasSaveProxy.class.getSimpleName();
private final Canvas mCanvas;

AndroidPCanvasSaveProxy(final Canvas canvas) {
Log.d(TAG, "New AndroidPCanvasSaveProxy");

mCanvas = canvas;
}

@Override
public int save() {
return mCanvas.save();
}

@Override
public boolean isFor(final Canvas canvas) {
return canvas == mCanvas;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sothree.slidinguppanel.canvassaveproxy;

import android.graphics.Canvas;

public interface CanvasSaveProxy {
int save();

boolean isFor(final Canvas canvas);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.sothree.slidinguppanel.canvassaveproxy;

import android.graphics.Canvas;
import android.os.Build;

public class CanvasSaveProxyFactory {

public CanvasSaveProxy create(final Canvas canvas) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return new AndroidPCanvasSaveProxy(canvas);
} else {
return new LegacyCanvasSaveProxy(canvas);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.sothree.slidinguppanel.canvassaveproxy;

import android.graphics.Canvas;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Deprecated
class LegacyCanvasSaveProxy implements CanvasSaveProxy {
private static final String TAG = CanvasSaveProxy.class.getSimpleName();
private static final String METHOD_NAME = "save";
private static final String FIELD_NAME = "CLIP_SAVE_FLAG";

private final Canvas mCanvas;
private final Method mSaveMethod;
private final int mClipSaveFlag;

LegacyCanvasSaveProxy(final Canvas canvas) {
Log.d(TAG, "New LegacyCanvasSaveProxy");

mCanvas = canvas;
mSaveMethod = findSaveMethod();
mClipSaveFlag = getClipSaveFlagValue();
}

@Override
public int save() {
return invokeSave();
}

@Override
public boolean isFor(final Canvas canvas) {
return canvas == mCanvas;
}

private int getClipSaveFlagValue() {
final Field constantField;
try {
constantField = Canvas.class.getDeclaredField(FIELD_NAME);
return (int) constantField.get(null);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Failed to get value of " + FIELD_NAME + " - NoSuchFieldException", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to get value of " + FIELD_NAME + " - IllegalAccessException", e);
}
}

private Method findSaveMethod() {
try {
return Canvas.class.getMethod(METHOD_NAME, int.class);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Canvas does not contain a method with signature save(int)");
}
}

private int invokeSave() {
try {
return (int) mSaveMethod.invoke(mCanvas, mClipSaveFlag);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to execute save(int) - IllegalAccessException", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Failed to execute save(int) - InvocationTargetException", e);
}
}
}

0 comments on commit 7af57e8

Please sign in to comment.