Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 35
buildToolsVersion "35.0.1"

namespace "per.goweii.android.swipeback"

defaultConfig {
applicationId "per.goweii.android.swipeback"
minSdkVersion 19
targetSdkVersion 30
targetSdkVersion 35
versionCode 1
versionName "1.0"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="per.goweii.android.swipeback">
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import per.goweii.swipeback.transformer.R;
import per.goweii.swipeback.SwipeBackDirection;
import per.goweii.swipeback.SwipeBackTransformer;
import per.goweii.swipeback.transformer.ParallaxSwipeBackTransformer;
Expand Down
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 {
maven { url "https://jitpack.io" }
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
classpath "com.android.tools.build:gradle:8.7.0"
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
26 changes: 23 additions & 3 deletions swipeback-transformer/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
plugins {
id 'com.android.library'
id 'maven-publish'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 35
buildToolsVersion "35.0.1"

namespace "per.goweii.swipeback.transformer"

defaultConfig {
minSdkVersion 16
targetSdkVersion 30
targetSdkVersion 35
versionCode 1
versionName "1.0"

Expand All @@ -26,9 +29,26 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
publishing {
singleVariant("release")
}
}

dependencies {
implementation project(":swipeback")
implementation 'androidx.appcompat:appcompat:1.2.0'
}

publishing {
publications {
release(MavenPublication) {
groupId = 'com.goweii'
artifactId = 'swipeback-transformer'
version = '*'

afterEvaluate {
from components.release
}
}
}
}
2 changes: 1 addition & 1 deletion swipeback-transformer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="per.goweii.swipeback.transformer" />
<manifest/>
26 changes: 23 additions & 3 deletions swipeback/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
plugins {
id 'com.android.library'
id 'maven-publish'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
compileSdkVersion 35
buildToolsVersion "35.0.1"

namespace "per.goweii.swipeback"

defaultConfig {
minSdkVersion 16
targetSdkVersion 30
targetSdkVersion 35
versionCode 1
versionName "1.0"

Expand All @@ -26,8 +29,25 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
publishing {
singleVariant("release")
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
}

publishing {
publications {
release(MavenPublication) {
groupId = 'com.goweii'
artifactId = 'swipeback'
version = '*'

afterEvaluate {
from components.release
}
}
}
}
2 changes: 1 addition & 1 deletion swipeback/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<manifest package="per.goweii.swipeback" />
<manifest/>
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@SuppressWarnings({"rawtypes", "JavaReflectionMemberAccess", "DiscouragedPrivateApi"})
public class TranslucentConverter {
Expand All @@ -29,6 +26,7 @@ public boolean isTranslucent() {

public boolean isThemeTranslucent() {
try {
//noinspection resource
TypedArray typedArray = mActivity.getTheme().obtainStyledAttributes(new int[]{android.R.attr.windowIsTranslucent});
boolean windowIsTranslucent = typedArray.getBoolean(0, false);
typedArray.recycle();
Expand All @@ -40,12 +38,8 @@ public boolean isThemeTranslucent() {

public void toTranslucent() {
if (mIsTranslucent) return;
ToConverter.convert(mActivity, new TranslucentConverter.TranslucentCallback() {
@Override
public void onTranslucentCallback(boolean translucent) {
mIsTranslucent = translucent;
}
});
ToConverter.convert(mActivity);
this.mIsTranslucent = true;
}

public void fromTranslucent() {
Expand All @@ -59,6 +53,16 @@ private static class FromConverter {
private static Method mMethodConvertFromTranslucent = null;

private static void convert(@NonNull Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.setTranslucent(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
activity.clearOverrideActivityTransition(Activity.OVERRIDE_TRANSITION_CLOSE);
} else {
int[] animations = getActivityCloseAnimation(activity);
activity.overridePendingTransition(animations[0], animations[1]);
}
return;
}
if (mInitialedConvertFromTranslucent && mMethodConvertFromTranslucent == null) {
return;
}
Expand All @@ -73,6 +77,23 @@ private static void convert(@NonNull Activity activity) {
} catch (Throwable ignored) {
}
}

private static int[] getActivityCloseAnimation(@NonNull Activity activity) {
int enterAnim = 0;
int exitAnim = 0;
try {
//noinspection resource
TypedArray typedArray = activity.getTheme().obtainStyledAttributes(new int[]{
android.R.attr.activityCloseEnterAnimation,
android.R.attr.activityCloseExitAnimation
});
enterAnim = typedArray.getResourceId(0, 0);
exitAnim = typedArray.getResourceId(1, 0);
typedArray.recycle();
} catch (Throwable ignore) {
}
return new int[]{enterAnim, exitAnim};
}
}

private static class ToConverter {
Expand All @@ -81,74 +102,48 @@ private static class ToConverter {
private static Method mMethodConvertToTranslucent = null;
private static Method mMethodGetActivityOptions = null;

private static void convert(@NonNull Activity activity, final TranslucentCallback callback) {
if (mInitialedConvertToTranslucent && mMethodConvertToTranslucent == null) {
if (callback != null) {
callback.onTranslucentCallback(false);
private static void convert(@NonNull Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.setTranslucent(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
activity.overrideActivityTransition(Activity.OVERRIDE_TRANSITION_CLOSE, 0, 0);
} else {
activity.overridePendingTransition(0, 0);
}
return;
}
if (mInitialedConvertToTranslucent && mMethodConvertToTranslucent == null) {
return;
}
try {
Object translucentConversionListener = getTranslucentConversionListener(callback);
if (mTranslucentConversionListenerClass == null) {
Class[] clazzArray = Activity.class.getDeclaredClasses();
for (Class clazz : clazzArray) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
mTranslucentConversionListenerClass = clazz;
}
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
convertActivityToTranslucentAboveL(activity, translucentConversionListener);
convertActivityToTranslucentAboveL(activity);
} else {
convertActivityToTranslucentBelowL(activity, translucentConversionListener);
}
if (translucentConversionListener == null) {
if (callback != null) {
callback.onTranslucentCallback(false);
}
convertActivityToTranslucentBelowL(activity);
}
} catch (Throwable ignored) {
if (callback != null) {
callback.onTranslucentCallback(false);
}
}
}

private static Object getTranslucentConversionListener(@Nullable final TranslucentCallback callback) throws Throwable {
if (mTranslucentConversionListenerClass == null) {
Class[] clazzArray = Activity.class.getDeclaredClasses();
for (Class clazz : clazzArray) {
if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
mTranslucentConversionListenerClass = clazz;
}
}
}
if (mTranslucentConversionListenerClass == null) {
return null;
}
return Proxy.newProxyInstance(
mTranslucentConversionListenerClass.getClassLoader(),
new Class[]{mTranslucentConversionListenerClass},
new InvocationHandler() {
@SuppressWarnings("SuspiciousInvocationHandlerImplementation")
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean translucent = false;
if (args != null && args.length == 1) {
translucent = (Boolean) args[0];
}
if (callback != null) {
callback.onTranslucentCallback(translucent);
}
return null;
}
});
}

private static void convertActivityToTranslucentBelowL(@NonNull Activity activity, @Nullable Object translucentConversionListener) throws Throwable {
private static void convertActivityToTranslucentBelowL(@NonNull Activity activity) throws Throwable {
if (mMethodConvertToTranslucent == null) {
mInitialedConvertToTranslucent = true;
Method method = Activity.class.getDeclaredMethod("convertToTranslucent", mTranslucentConversionListenerClass);
method.setAccessible(true);
mMethodConvertToTranslucent = method;
}
mMethodConvertToTranslucent.invoke(activity, translucentConversionListener);
mMethodConvertToTranslucent.invoke(activity, (Object) null);
}

private static void convertActivityToTranslucentAboveL(@NonNull Activity activity, @Nullable Object translucentConversionListener) throws Throwable {
private static void convertActivityToTranslucentAboveL(@NonNull Activity activity) throws Throwable {
if (mMethodConvertToTranslucent == null) {
mInitialedConvertToTranslucent = true;
Method getActivityOptions = Activity.class.getDeclaredMethod("getActivityOptions");
Expand All @@ -159,11 +154,7 @@ private static void convertActivityToTranslucentAboveL(@NonNull Activity activit
mMethodConvertToTranslucent = method;
}
Object options = mMethodGetActivityOptions.invoke(activity);
mMethodConvertToTranslucent.invoke(activity, translucentConversionListener, options);
mMethodConvertToTranslucent.invoke(activity, null, options);
}
}

public interface TranslucentCallback {
void onTranslucentCallback(boolean translucent);
}
}