Skip to content

Commit

Permalink
Fix insets, insets-extensions, and insets-helper after targeting SDK 29
Browse files Browse the repository at this point in the history
  • Loading branch information
consp1racy committed Oct 6, 2019
1 parent 111a2c6 commit 3ba7db3
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 74 deletions.
2 changes: 1 addition & 1 deletion insets-extensions/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation project(':insets')
api project(':insets')

implementation 'androidx.annotation:annotation:1.0.2'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,29 @@
package net.xpece.androidx.optical

import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.graphics.Insets
import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
import android.os.Build
import android.os.Build.VERSION_CODES
import androidx.annotation.RequiresApi
import android.util.Log
import android.view.View
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.LazyThreadSafetyMode.NONE

private val viewInsetsGetter by lazy(NONE) {
//noinspection SoonBlockedPrivateApi
View::class.java.getDeclaredMethod("getOpticalInsets")
}

/**
* Returns the insets that will be used during optical bounds layout mode.
*/
@SuppressLint("NewApi")
@Deprecated("Shadows platform call. Doesn't work on API 29+.")
@RequiresApi(16)
fun View.getOpticalInsets(): Insets = viewInsetsGetter.invoke(this) as Insets

Expand All @@ -34,9 +39,12 @@ private val drawableInsetsGetter by lazy(NONE) {
}
}

@Suppress("NOTHING_TO_INLINE")
private inline fun Drawable.getActualOpticalInsets(): Insets =
@TargetApi(29)
private fun Drawable.getActualOpticalInsets(): Insets = if (Build.VERSION.SDK_INT < 18) {
drawableInsetsGetter.invoke(this) as Insets
} else {
opticalInsets
}

private val isLoggedInsetDrawableReflectionError = AtomicBoolean(false)
private val isLoggedLayerDrawableReflectionError = AtomicBoolean(false)
Expand All @@ -45,39 +53,52 @@ private val isLoggedLayerDrawableReflectionError = AtomicBoolean(false)
* Returns the layout insets suggested by this Drawable for use with alignment
* operations during layout.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
@Deprecated("Shadows platform call.", replaceWith = ReplaceWith("getOpticalInsetsCompat"))
@RequiresApi(16)
fun Drawable.getOpticalInsets(): Insets = getOpticalInsetsCompat()

/**
* Returns the layout insets suggested by this Drawable for use with alignment
* operations during layout.
*/
@Suppress("LiftReturnOrAssignment")
@RequiresApi(16)
fun Drawable.getOpticalInsets(): Insets = if (Build.VERSION.SDK_INT < 21 && this is InsetDrawable) {
val actual = getActualOpticalInsets()
if (actual == InsetsCompat.NONE) {
try {
InsetDrawableReflection.getOpticalInsets(this)
} catch (ex: Throwable) {
if (!isLoggedInsetDrawableReflectionError.getAndSet(true)) {
Log.w(
"OpticalInsets",
"Couldn't access InsetDrawable data using reflection. Oh well...",
ex
)
fun Drawable.getOpticalInsetsCompat(): Insets {
if (Build.VERSION.SDK_INT < 21 && this is InsetDrawable) {
val actual = getActualOpticalInsets()
if (actual == InsetsCompat.NONE) {
try {
return InsetDrawableReflection.getOpticalInsets(this)
} catch (ex: Throwable) {
if (!isLoggedInsetDrawableReflectionError.getAndSet(true)) {
Log.w(
"OpticalInsets",
"Couldn't access InsetDrawable data using reflection. Oh well...",
ex
)
}
return actual
}
actual
} else {
return actual
}
} else if (this is LayerDrawable) {
val actual = getActualOpticalInsets()
if (actual == InsetsCompat.NONE) {
val allInsets = Array(numberOfLayers, this::getTotalLayerInsets)
return InsetsCompat.union(*allInsets)
} else {
return actual
}
} else {
actual
}
} else if (this is LayerDrawable) {
val actual = getActualOpticalInsets()
if (actual == InsetsCompat.NONE) {
val allInsets = Array(numberOfLayers, this::getTotalLayerInsets)
InsetsCompat.union(*allInsets)
} else {
actual
return getActualOpticalInsets()
}
} else {
getActualOpticalInsets()
}

@TargetApi(29)
private fun LayerDrawable.getTotalLayerInsets(i: Int): Insets = if (Build.VERSION.SDK_INT >= 23) {
val drawableInsets = getDrawable(i).getOpticalInsets()
val drawableInsets = getDrawable(i).getOpticalInsetsCompat()
InsetsCompat.of(
getLayerInsetLeft(i) + drawableInsets.left,
getLayerInsetTop(i) + drawableInsets.top,
Expand Down Expand Up @@ -127,8 +148,10 @@ private object LayerDrawableReflection {
.apply { isAccessible = true }

@RequiresApi(16)
@TargetApi(29)
@SuppressLint("NewApi")
internal fun getTotalLayerInsets(drawable: LayerDrawable, i: Int): Insets {
val drawableInsets = drawable.getDrawable(i).getOpticalInsets()
val drawableInsets = drawable.getDrawable(i).getOpticalInsetsCompat()
val state = fieldLayerState.get(drawable)
val children = fieldChildren.get(state) as Array<*>
val layer = children[i]
Expand Down
4 changes: 0 additions & 4 deletions insets-helper/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'digital.wup.android-maven-publish'

android {
Expand All @@ -21,9 +20,6 @@ android {
}

dependencies {
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation project(':insets')
implementation project(':insets-extensions')

implementation 'androidx.annotation:annotation:1.0.2'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.xpece.androidx.optical;

import android.annotation.TargetApi;
import android.graphics.Insets;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.RequiresApi;

/**
* Helper class for making views aware of optical insets
* on {@link android.graphics.drawable.InsetDrawable InsetDrawable} below API 21,
* and {@link android.graphics.drawable.LayerDrawable LayerDrawable} (including children
* such as {@link android.graphics.drawable.RippleDrawable RippleDrawable}) on all API levels.
*/
@RequiresApi(16)
public final class OpticalInsetsHelper {

private final View view;

private Insets opticalInsets = null;

public OpticalInsetsHelper(final View view) {
this.view = view;
}

/**
* Return this from {@code View#getOpticalInsets()}.
*/
@TargetApi(29)
public Insets onGetOpticalInsets() {
if (opticalInsets == null) {
// Same as platform, we don't support changing insets once resolved.
final Drawable background = view.getBackground();
opticalInsets = background != null ? background.getOpticalInsets() : InsetsCompat.NONE;
// If background.getOpticalInsets() returns null this will blow up.
}
return opticalInsets;
}

/**
* Call this from {@code View#setOpticalInsets(Insets)}.
*/
public void onSetOpticalInsets(final Insets insets) {
if (opticalInsets != insets) {
opticalInsets = insets;
view.requestLayout();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.xpece.androidx.optical;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.drawable.InsetDrawable;
Expand All @@ -18,6 +20,7 @@
* Insets are immutable so may be treated as values.
*/
@RequiresApi(16)
@TargetApi(29)
@SuppressWarnings("unused")
public final class InsetsCompat {

Expand Down Expand Up @@ -51,6 +54,7 @@ private InsetsCompat() {
* @param bottom the bottom inset
* @return Insets instance with the appropriate values
*/
@SuppressLint("NewApi")
public static Insets of(int left, int top, int right, int bottom) {
if (sSafe) {
return Insets.of(left, top, right, bottom);
Expand All @@ -74,6 +78,7 @@ public static Insets of(@Nullable Rect r) {
}
}

@SuppressLint("NewApi")
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
static Insets union(final @NonNull Insets... insets) {
int left = 0, top = 0, right = 0, bottom = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import net.xpece.androidx.optical.getOpticalInsets
import net.xpece.androidx.optical.getOpticalInsetsCompat

class MainActivity : AppCompatActivity() {

Expand Down Expand Up @@ -48,6 +48,6 @@ class MainActivity : AppCompatActivity() {
navigation.selectedItemId = R.id.navigation_wrong
}

LayerDrawable(arrayOf(ColorDrawable(0))).getOpticalInsets()
LayerDrawable(arrayOf(ColorDrawable(0))).getOpticalInsetsCompat()
}
}

0 comments on commit 3ba7db3

Please sign in to comment.