|
1 | 1 | package com.th3rdwave.safeareacontext |
2 | 2 |
|
3 | 3 | import android.content.Context |
| 4 | +import android.util.Log |
4 | 5 | import android.view.ViewGroup |
5 | | -import android.view.ViewTreeObserver |
| 6 | +import androidx.core.view.ViewCompat |
| 7 | +import androidx.core.view.WindowInsetsCompat |
6 | 8 | import com.facebook.react.views.view.ReactViewGroup |
7 | 9 |
|
| 10 | +const val DEBUG = false |
| 11 | + |
8 | 12 | typealias OnInsetsChangeHandler = (view: SafeAreaProvider, insets: EdgeInsets, frame: Rect) -> Unit |
9 | 13 |
|
10 | | -class SafeAreaProvider(context: Context?) : |
11 | | - ReactViewGroup(context), ViewTreeObserver.OnPreDrawListener { |
| 14 | +class SafeAreaProvider(context: Context?) : ReactViewGroup(context) { |
12 | 15 | private var mInsetsChangeHandler: OnInsetsChangeHandler? = null |
13 | | - private var mLastInsets: EdgeInsets? = null |
14 | | - private var mLastFrame: Rect? = null |
| 16 | + private var mCurrentInsets: EdgeInsets = EdgeInsets(0.0f, 0.0f, 0.0f, 0.0f) |
15 | 17 |
|
16 | | - private fun maybeUpdateInsets() { |
17 | | - val insetsChangeHandler = mInsetsChangeHandler ?: return |
18 | | - val edgeInsets = getSafeAreaInsets(this) ?: return |
19 | | - val frame = getFrame(rootView as ViewGroup, this) ?: return |
20 | | - if (mLastInsets != edgeInsets || mLastFrame != frame) { |
21 | | - insetsChangeHandler(this, edgeInsets, frame) |
22 | | - mLastInsets = edgeInsets |
23 | | - mLastFrame = frame |
| 18 | + init { |
| 19 | + ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets -> |
| 20 | + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) |
| 21 | + |
| 22 | + mCurrentInsets = EdgeInsets( |
| 23 | + systemBars.top.toFloat(), |
| 24 | + systemBars.left.toFloat(), |
| 25 | + systemBars.bottom.toFloat(), |
| 26 | + systemBars.right.toFloat()) |
| 27 | + |
| 28 | + if (DEBUG) { |
| 29 | + Log.d("SafeAreaProvider", "calculated insets: $mCurrentInsets") |
| 30 | + } |
| 31 | + |
| 32 | + sendInsetValuesToJs() |
| 33 | + |
| 34 | + insets |
24 | 35 | } |
25 | 36 | } |
26 | 37 |
|
27 | | - override fun onAttachedToWindow() { |
28 | | - super.onAttachedToWindow() |
29 | | - viewTreeObserver.addOnPreDrawListener(this) |
30 | | - maybeUpdateInsets() |
31 | | - } |
| 38 | + private fun sendInsetValuesToJs() { |
| 39 | + val insetsChangeHandler = mInsetsChangeHandler ?: return |
| 40 | + val frame = getFrame(rootView as ViewGroup, this) ?: return |
32 | 41 |
|
33 | | - override fun onDetachedFromWindow() { |
34 | | - super.onDetachedFromWindow() |
35 | | - viewTreeObserver.removeOnPreDrawListener(this) |
36 | | - } |
| 42 | + if (DEBUG) { |
| 43 | + Log.d("SafeAreaProvider", "emitting updated insets: $mCurrentInsets") |
| 44 | + } |
37 | 45 |
|
38 | | - override fun onPreDraw(): Boolean { |
39 | | - maybeUpdateInsets() |
40 | | - return true |
| 46 | + insetsChangeHandler(this, mCurrentInsets, frame) |
41 | 47 | } |
42 | 48 |
|
43 | 49 | fun setOnInsetsChangeHandler(handler: OnInsetsChangeHandler?) { |
44 | 50 | mInsetsChangeHandler = handler |
45 | | - maybeUpdateInsets() |
| 51 | + sendInsetValuesToJs() |
| 52 | + } |
| 53 | + |
| 54 | + override fun onAttachedToWindow() { |
| 55 | + super.onAttachedToWindow() |
| 56 | + |
| 57 | + if (DEBUG) { |
| 58 | + Log.d("SafeAreaProvider", "attached to window") |
| 59 | + } |
| 60 | + |
| 61 | + requestApplyInsets() |
46 | 62 | } |
47 | 63 | } |
0 commit comments