Skip to content

Commit 1edf41f

Browse files
authored
fix: don't use @RequiresApi with old SDK versions (#1107)
## 📜 Description Removed `@RequiresApi` annotations usage. ## 💡 Motivation and Context When I was getting compilation issues due to usage of API which is not available in older versions I was constantly using first option provided by Android Studio: to add `@RequiresApi` annotation. However it has some downsides: - if you mark one method with this annotation - all other methods must use the same annotation if they call this method; - this method is kind of semantic, and if you somehow accidentally call this method on older devices it will lead to crash. So to make code structure a little bit cleaner I decided to remove those annotations and switch to `if`-statements. Initially the idea was to fix #1104, but turned out that [ObsoleteSdkInt] checks also `if`-statements. So for me as a library author there is only one reliable way to fix the issue is to suppress those warnings (if people set linter to treat warnings as errors it will prevent the lib from being compiled) Closes #1104 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### Android - rewrite `@RequiresApi` to `if`-statements; - suppress new `if`-statements lint warnings via `@SuppressLint`; ## 🤔 How Has This Been Tested? Tested in example app. ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 1946dcd commit 1edf41f

File tree

4 files changed

+44
-43
lines changed

4 files changed

+44
-43
lines changed

android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package com.reactnativekeyboardcontroller.extensions
22

3+
import android.annotation.SuppressLint
34
import android.graphics.Rect
45
import android.os.Build
56
import android.view.View
6-
import androidx.annotation.RequiresApi
77
import com.reactnativekeyboardcontroller.log.Logger
88

99
/**
1010
* Call this every time when using [ViewCompat.setOnApplyWindowInsetsListener]
1111
* to ensure that insets are always received.
1212
* @see https://stackoverflow.com/a/61909205/9272042
1313
*/
14+
@SuppressLint("ObsoleteSdkInt")
1415
fun View.requestApplyInsetsWhenAttached() {
1516
// https://chris.banes.dev/2019/04/12/insets-listeners-to-layouts/
1617
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT && isAttachedToWindow) {
@@ -38,14 +39,16 @@ private val tmpIntArr = IntArray(2)
3839
/**
3940
* Function which updates the given [rect] with this view's position and bounds in its window.
4041
*/
41-
@RequiresApi(Build.VERSION_CODES.KITKAT)
42+
@SuppressLint("ObsoleteSdkInt")
4243
fun View.copyBoundsInWindow(rect: Rect) {
43-
if (isAttachedToWindow) {
44-
rect.set(0, 0, width, height)
45-
getLocationInWindow(tmpIntArr)
46-
rect.offset(tmpIntArr[0], tmpIntArr[1])
47-
} else {
48-
Logger.w("View.copyBoundsInWindow", "Can not copy bounds as view is not attached to window")
44+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
45+
if (isAttachedToWindow) {
46+
rect.set(0, 0, width, height)
47+
getLocationInWindow(tmpIntArr)
48+
rect.offset(tmpIntArr[0], tmpIntArr[1])
49+
} else {
50+
Logger.w("View.copyBoundsInWindow", "Can not copy bounds as view is not attached to window")
51+
}
4952
}
5053
}
5154

android/src/main/java/com/reactnativekeyboardcontroller/modules/statusbar/StatusBarManagerCompatModuleImpl.kt

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package com.reactnativekeyboardcontroller.modules.statusbar
22

33
import android.animation.ArgbEvaluator
44
import android.animation.ValueAnimator
5+
import android.annotation.SuppressLint
56
import android.app.Activity
67
import android.os.Build
7-
import androidx.annotation.RequiresApi
88
import androidx.core.view.WindowInsetsCompat
99
import androidx.core.view.WindowInsetsControllerCompat
1010
import com.facebook.react.bridge.ReactApplicationContext
@@ -37,37 +37,39 @@ class StatusBarManagerCompatModuleImpl(
3737
}
3838
}
3939

40-
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
40+
@SuppressLint("ObsoleteSdkInt")
4141
fun setColor(
4242
color: Int,
4343
animated: Boolean,
4444
) {
45-
if (!isEnabled()) {
46-
return original.setColor(color.toDouble(), animated)
47-
}
48-
49-
val activity = mReactContext.currentActivity
50-
if (activity == null) {
51-
Logger.w(
52-
TAG,
53-
"StatusBarManagerCompatModule: Ignored status bar change, current activity is null.",
54-
)
55-
return
56-
}
45+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
46+
if (!isEnabled()) {
47+
return original.setColor(color.toDouble(), animated)
48+
}
5749

58-
UiThreadUtil.runOnUiThread {
59-
val window = activity.window
50+
val activity = mReactContext.currentActivity
51+
if (activity == null) {
52+
Logger.w(
53+
TAG,
54+
"StatusBarManagerCompatModule: Ignored status bar change, current activity is null.",
55+
)
56+
return
57+
}
6058

61-
if (animated) {
62-
val curColor: Int = window.statusBarColor
63-
val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), curColor, color)
64-
colorAnimation.addUpdateListener { animator ->
65-
window.statusBarColor = animator.animatedValue as Int
59+
UiThreadUtil.runOnUiThread {
60+
val window = activity.window
61+
62+
if (animated) {
63+
val curColor: Int = window.statusBarColor
64+
val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), curColor, color)
65+
colorAnimation.addUpdateListener { animator ->
66+
window.statusBarColor = animator.animatedValue as Int
67+
}
68+
colorAnimation.setDuration(DEFAULT_ANIMATION_TIME).startDelay = 0
69+
colorAnimation.start()
70+
} else {
71+
window.statusBarColor = color
6672
}
67-
colorAnimation.setDuration(DEFAULT_ANIMATION_TIME).startDelay = 0
68-
colorAnimation.start()
69-
} else {
70-
window.statusBarColor = color
7173
}
7274
}
7375
}

android/src/main/java/com/reactnativekeyboardcontroller/views/KeyboardGestureAreaReactViewGroup.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.os.Build
66
import android.view.MotionEvent
77
import android.view.VelocityTracker
88
import android.view.ViewConfiguration
9-
import androidx.annotation.RequiresApi
109
import androidx.core.view.ViewCompat
1110
import androidx.core.view.WindowInsetsCompat
1211
import com.facebook.react.uimanager.ThemedReactContext
@@ -50,7 +49,6 @@ class KeyboardGestureAreaReactViewGroup(
5049

5150
private var velocityTracker: VelocityTracker? = null
5251

53-
@RequiresApi(Build.VERSION_CODES.R)
5452
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
5553
if (velocityTracker == null) {
5654
// Obtain a VelocityTracker if we don't have one yet
@@ -86,7 +84,6 @@ class KeyboardGestureAreaReactViewGroup(
8684
// endregion
8785

8886
// region Handlers
89-
@RequiresApi(Build.VERSION_CODES.KITKAT)
9087
private fun onActionDown(event: MotionEvent) {
9188
velocityTracker?.addMovement(event)
9289

@@ -97,7 +94,6 @@ class KeyboardGestureAreaReactViewGroup(
9794
lastWindowY = bounds.top
9895
}
9996

100-
@RequiresApi(Build.VERSION_CODES.R)
10197
private fun onActionMove(event: MotionEvent) {
10298
// Since the view is likely to be translated/moved as the WindowInsetsAnimation
10399
// progresses, we need to make sure we account for that change in our touch
@@ -230,11 +226,14 @@ class KeyboardGestureAreaReactViewGroup(
230226
else -> false
231227
}
232228

233-
@RequiresApi(Build.VERSION_CODES.R)
234229
private fun getWindowHeight(): Int {
235-
val metrics = reactContext.currentActivity?.windowManager?.currentWindowMetrics
230+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
231+
val metrics = reactContext.currentActivity?.windowManager?.currentWindowMetrics
236232

237-
return metrics?.bounds?.height() ?: 0
233+
return metrics?.bounds?.height() ?: 0
234+
}
235+
236+
return 0
238237
}
239238

240239
companion object {

android/src/paper/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.reactnativekeyboardcontroller
22

3-
import android.os.Build
4-
import androidx.annotation.RequiresApi
53
import com.facebook.react.bridge.ReactApplicationContext
64
import com.facebook.react.bridge.ReactContextBaseJavaModule
75
import com.facebook.react.bridge.ReactMethod
@@ -22,7 +20,6 @@ class StatusBarManagerCompatModule(
2220
}
2321

2422
@ReactMethod
25-
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
2623
private fun setColor(
2724
color: Int,
2825
animated: Boolean,

0 commit comments

Comments
 (0)