diff --git a/android/src/main/java/com/th3rdwave/safeareacontext/EdgeInsets.kt b/android/src/main/java/com/th3rdwave/safeareacontext/EdgeInsets.kt index e71af8fa..b34e7a11 100644 --- a/android/src/main/java/com/th3rdwave/safeareacontext/EdgeInsets.kt +++ b/android/src/main/java/com/th3rdwave/safeareacontext/EdgeInsets.kt @@ -1,3 +1,7 @@ package com.th3rdwave.safeareacontext -data class EdgeInsets(val top: Float, val right: Float, val bottom: Float, val left: Float) +data class EdgeInsets(val top: Float, val right: Float, val bottom: Float, val left: Float) { + override fun toString(): String { + return "(top=${top}, right=${right}, bottom=${bottom}, left=${left})" + } +} diff --git a/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProvider.kt b/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProvider.kt index eec0626f..38f8f8f2 100644 --- a/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProvider.kt +++ b/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProvider.kt @@ -1,47 +1,63 @@ package com.th3rdwave.safeareacontext import android.content.Context +import android.util.Log import android.view.ViewGroup -import android.view.ViewTreeObserver +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import com.facebook.react.views.view.ReactViewGroup +const val DEBUG = false + typealias OnInsetsChangeHandler = (view: SafeAreaProvider, insets: EdgeInsets, frame: Rect) -> Unit -class SafeAreaProvider(context: Context?) : - ReactViewGroup(context), ViewTreeObserver.OnPreDrawListener { +class SafeAreaProvider(context: Context?) : ReactViewGroup(context) { private var mInsetsChangeHandler: OnInsetsChangeHandler? = null - private var mLastInsets: EdgeInsets? = null - private var mLastFrame: Rect? = null + private var mCurrentInsets: EdgeInsets = EdgeInsets(0.0f, 0.0f, 0.0f, 0.0f) - private fun maybeUpdateInsets() { - val insetsChangeHandler = mInsetsChangeHandler ?: return - val edgeInsets = getSafeAreaInsets(this) ?: return - val frame = getFrame(rootView as ViewGroup, this) ?: return - if (mLastInsets != edgeInsets || mLastFrame != frame) { - insetsChangeHandler(this, edgeInsets, frame) - mLastInsets = edgeInsets - mLastFrame = frame + init { + ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + + mCurrentInsets = EdgeInsets( + systemBars.top.toFloat(), + systemBars.left.toFloat(), + systemBars.bottom.toFloat(), + systemBars.right.toFloat()) + + if (DEBUG) { + Log.d("SafeAreaProvider", "calculated insets: $mCurrentInsets") + } + + sendInsetValuesToJs() + + insets } } - override fun onAttachedToWindow() { - super.onAttachedToWindow() - viewTreeObserver.addOnPreDrawListener(this) - maybeUpdateInsets() - } + private fun sendInsetValuesToJs() { + val insetsChangeHandler = mInsetsChangeHandler ?: return + val frame = getFrame(rootView as ViewGroup, this) ?: return - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - viewTreeObserver.removeOnPreDrawListener(this) - } + if (DEBUG) { + Log.d("SafeAreaProvider", "emitting updated insets: $mCurrentInsets") + } - override fun onPreDraw(): Boolean { - maybeUpdateInsets() - return true + insetsChangeHandler(this, mCurrentInsets, frame) } fun setOnInsetsChangeHandler(handler: OnInsetsChangeHandler?) { mInsetsChangeHandler = handler - maybeUpdateInsets() + sendInsetValuesToJs() + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + + if (DEBUG) { + Log.d("SafeAreaProvider", "attached to window") + } + + requestApplyInsets() } }