Skip to content

Commit

Permalink
style: improve Kotlin code (#1558)
Browse files Browse the repository at this point in the history
* chore: add method for resolving appropriate fragment manager

* fix: resolve appropriate fragment manager

* refact: change method name

* chore: make return type non nullable

* chore: clarify comments & simplify logic

* chore: refactor code & add checks

* fix: typo

* refact: another typo

* chore: take advantage of FragmentManager#findFragment method

Also add some comments that describe the changes

* chore: add link to the issue

* refact: use checkNotNull in place of explicit comparision against null

* style: Kotlin

* refact: ScreenContainer#createTransaction

* refact: ScreenContainer#{getActivityState,hasScreen}

* refact: ScreenContainer#getScreenAt

* refact: ScreenContainer#removeMyFragments

* refact: ScreenContainer#topScreen

* refact: ScreenContainer#onMeasure

* refact: ScreenContainer#onUpdate

* refact: ScreenStackViewManager#getName

* refact: ScreenStackViewManager#createViewInstance

* refact: ScreenStackViewManager#startTransitionRecursive

* refact: ScreenStackViewManager#(series of getters)

* refact: ScreenStackFragment#setToolbar

* refact: ScreenStackFragment#onContainerUpdate

* refact: ScreenStackFragment#onCreateView

* refact: ScreenStackFragment#updateToolbarMenu

* refact: ScreenStackFragment#startAnimation

* refact: CustomSearchView

* refact: LifecycleHelper#unregister

* refact: RNSScreenPackage#createNativeModules

* refact: Screen#headerConfig

* refact: ScreenContainerViewManager

* refact: ScreenFragment#onCreateView

* refact: ScreenFragment#canDispatchEvent

* refact: ScreenFragment#dispatchEventInChildContainers

* refact: ScreenFragment#dispatchHeaderBackButtonClickedEvent

* refact: ScreenFragment#dispatchTransitionProgress

* refact: ScreenFragment#onDestroy

* refact: ScreenStack#rootScreen

* refact: ScreenStack#adapt

* refact: ScreenStack#dispatchonfinishTransitioning

* refact: ScreenStack#removeScreenAt

* refact: ScreenStack#hasScreen

* refact: spotless for ScreenContainer

* chore: add RNSUtil with forEachSatisfying method

* refact: ScreenStack#notifyContainerUpdate

* refact: ScreenStack#obtainDrawingOp

* refact: ScreenStack#companion

* refact: ScreenStackHeaderConfig#screen

* refact: ScreenStackHeaderConfig#screenStack

* refact: ScreenStackHeaderConfig#onUpdate

* refact: ScreenStackHeaderConfig#getConfigSubview

* refact: ScreenStackHeaderConfig#titleTextView

* refact: ScreenStackHeaderConfigViewManager

* refact: ScreenStackHeaderSubview

* refact: ScreenStackHeaderSubview

* refact: ScreenStackheaderConfig#getName v2

* refact: ScreenViewManager

* refact: ScreenWindowTraits

* fix: ScreenStackHeaderSubview#config

* fix: restore initial logic in ScreenFragment#onCreateView

* style: apply review suggestions
  • Loading branch information
kkafar authored Sep 16, 2022
1 parent a07eec0 commit 870007d
Show file tree
Hide file tree
Showing 16 changed files with 148 additions and 263 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class CustomSearchView(context: Context, fragment: Fragment) : SearchView(contex
isIconified = true
}
}

private val backPressOverrider = FragmentBackPressOverrider(fragment, mOnBackPressedCallback)

var overrideBackAction: Boolean
set(value) {
backPressOverrider.overrideBackAction = value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ class LifecycleHelper {
}

fun <T> unregister(view: T) where T : View, T : LifecycleObserver? {
val lifecycle = mViewToLifecycleMap[view]
lifecycle?.removeObserver(view)
mViewToLifecycleMap[view]?.removeObserver(view)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class RNScreensPackage : ReactPackage {
// This should no longer be needed if RN's autolink mechanism has Fabric support
SoLoader.loadLibrary("rnscreens_modules")
}
return emptyList<NativeModule>()
return emptyList()
}

override fun createViewManagers(reactContext: ReactApplicationContext) =
Expand Down
7 changes: 1 addition & 6 deletions android/src/main/java/com/swmansion/rnscreens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
}

val headerConfig: ScreenStackHeaderConfig?
get() {
val child = getChildAt(0)
return if (child is ScreenStackHeaderConfig) {
child
} else null
}
get() = getChildAt(0) as? ScreenStackHeaderConfig

/**
* While transitioning this property allows to optimize rendering behavior on Android and provide
Expand Down
49 changes: 18 additions & 31 deletions android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
}
}
private var mParentScreenFragment: ScreenFragment? = null

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var i = 0
val size = childCount
Expand Down Expand Up @@ -116,19 +117,10 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
val screenCount: Int
get() = mScreenFragments.size

fun getScreenAt(index: Int): Screen {
return mScreenFragments[index].screen
}
fun getScreenAt(index: Int): Screen = mScreenFragments[index].screen

open val topScreen: Screen?
get() {
for (screenFragment in mScreenFragments) {
if (getActivityState(screenFragment) === ActivityState.ON_TOP) {
return screenFragment.screen
}
}
return null
}
get() = mScreenFragments.firstOrNull { getActivityState(it) === ActivityState.ON_TOP }?.screen

private fun setFragmentManager(fm: FragmentManager) {
mFragmentManager = fm
Expand Down Expand Up @@ -200,10 +192,9 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
}

protected fun createTransaction(): FragmentTransaction {
val fragmentManager = requireNotNull(mFragmentManager, { "mFragmentManager is null when creating transaction" })
val transaction = fragmentManager.beginTransaction()
transaction.setReorderingAllowed(true)
return transaction
return requireNotNull(mFragmentManager) { "mFragmentManager is null when creating transaction" }
.beginTransaction()
.setReorderingAllowed(true)
}

private fun attachScreen(transaction: FragmentTransaction, screenFragment: ScreenFragment) {
Expand All @@ -214,13 +205,11 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
transaction.remove(screenFragment)
}

private fun getActivityState(screenFragment: ScreenFragment): ActivityState? {
return screenFragment.screen.activityState
}
private fun getActivityState(screenFragment: ScreenFragment): ActivityState? =
screenFragment.screen.activityState

open fun hasScreen(screenFragment: ScreenFragment?): Boolean {
return mScreenFragments.contains(screenFragment)
}
open fun hasScreen(screenFragment: ScreenFragment?): Boolean =
mScreenFragments.contains(screenFragment)

override fun onAttachedToWindow() {
super.onAttachedToWindow()
Expand All @@ -233,9 +222,7 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
val transaction = fragmentManager.beginTransaction()
var hasFragments = false
for (fragment in fragmentManager.fragments) {
if (fragment is ScreenFragment &&
fragment.screen.container === this
) {
if (fragment is ScreenFragment && fragment.screen.container === this) {
transaction.remove(fragment)
hasFragments = true
}
Expand Down Expand Up @@ -276,19 +263,15 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
// children are not already detached, which may lead to calling `onDetachedFromWindow` on them
// twice.
// We also get the size earlier, because we will be removing child views in `for` loop.
val size = childCount
for (i in size - 1 downTo 0) {
for (i in childCount - 1 downTo 0) {
removeViewAt(i)
}
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
var i = 0
val size = childCount
while (i < size) {
for (i in 0 until childCount) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec)
i++
}
}

Expand Down Expand Up @@ -332,7 +315,11 @@ open class ScreenContainer<T : ScreenFragment>(context: Context?) : ViewGroup(co
open fun onUpdate() {
createTransaction().let {
// detach screens that are no longer active
val orphaned: MutableSet<Fragment> = HashSet(requireNotNull(mFragmentManager, { "mFragmentManager is null when performing update in ScreenContainer" }).fragments)
val orphaned: MutableSet<Fragment> = HashSet(
requireNotNull(mFragmentManager) {
"mFragmentManager is null when performing update in ScreenContainer"
}.fragments
)
for (screenFragment in mScreenFragments) {
if (getActivityState(screenFragment) === ActivityState.INACTIVE &&
screenFragment.isAdded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ import com.facebook.react.uimanager.ViewGroupManager

@ReactModule(name = ScreenContainerViewManager.REACT_CLASS)
class ScreenContainerViewManager : ViewGroupManager<ScreenContainer<*>>() {
override fun getName(): String {
return REACT_CLASS
}
override fun getName(): String = REACT_CLASS

override fun createViewInstance(reactContext: ThemedReactContext): ScreenContainer<ScreenFragment> {
return ScreenContainer(reactContext)
}
override fun createViewInstance(reactContext: ThemedReactContext): ScreenContainer<ScreenFragment> = ScreenContainer(reactContext)

override fun addView(parent: ScreenContainer<*>, child: View, index: Int) {
require(child is Screen) { "Attempt attach child that is not of type RNScreens" }
Expand All @@ -30,21 +26,13 @@ class ScreenContainerViewManager : ViewGroupManager<ScreenContainer<*>>() {
parent.removeAllScreens()
}

override fun getChildCount(parent: ScreenContainer<*>): Int {
return parent.screenCount
}
override fun getChildCount(parent: ScreenContainer<*>): Int = parent.screenCount

override fun getChildAt(parent: ScreenContainer<*>, index: Int): View {
return parent.getScreenAt(index)
}
override fun getChildAt(parent: ScreenContainer<*>, index: Int): View = parent.getScreenAt(index)

override fun createShadowNodeInstance(context: ReactApplicationContext): LayoutShadowNode {
return ScreensShadowNode(context)
}
override fun createShadowNodeInstance(context: ReactApplicationContext): LayoutShadowNode = ScreensShadowNode(context)

override fun needsCustomLayoutForChildren(): Boolean {
return true
}
override fun needsCustomLayoutForChildren(): Boolean = true

companion object {
const val REACT_CLASS = "RNSScreenContainer"
Expand Down
57 changes: 23 additions & 34 deletions android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,12 @@ open class ScreenFragment : Fragment {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val wrapper = context?.let { ScreensFrameLayout(it) }

val params = FrameLayout.LayoutParams(
screen.layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
screen.layoutParams = params
wrapper?.addView(recycleView(screen))
val wrapper = context?.let { ScreensFrameLayout(it) }?.apply {
addView(recycleView(screen))
}
return wrapper
}

Expand Down Expand Up @@ -153,13 +152,11 @@ open class ScreenFragment : Fragment {
val childScreenContainers: List<ScreenContainer<*>>
get() = mChildScreenContainers

private fun canDispatchEvent(event: ScreenLifecycleEvent): Boolean {
return when (event) {
ScreenLifecycleEvent.WillAppear -> canDispatchWillAppear
ScreenLifecycleEvent.Appear -> canDispatchAppear
ScreenLifecycleEvent.WillDisappear -> !canDispatchWillAppear
ScreenLifecycleEvent.Disappear -> !canDispatchAppear
}
private fun canDispatchEvent(event: ScreenLifecycleEvent): Boolean = when (event) {
ScreenLifecycleEvent.WillAppear -> canDispatchWillAppear
ScreenLifecycleEvent.Appear -> canDispatchAppear
ScreenLifecycleEvent.WillDisappear -> !canDispatchWillAppear
ScreenLifecycleEvent.Disappear -> !canDispatchAppear
}

private fun setLastEventDispatched(event: ScreenLifecycleEvent) {
Expand All @@ -173,25 +170,21 @@ open class ScreenFragment : Fragment {

private fun dispatchOnWillAppear() {
dispatchEvent(ScreenLifecycleEvent.WillAppear, this)

dispatchTransitionProgress(0.0f, false)
}

private fun dispatchOnAppear() {
dispatchEvent(ScreenLifecycleEvent.Appear, this)

dispatchTransitionProgress(1.0f, false)
}

private fun dispatchOnWillDisappear() {
dispatchEvent(ScreenLifecycleEvent.WillDisappear, this)

dispatchTransitionProgress(0.0f, true)
}

private fun dispatchOnDisappear() {
dispatchEvent(ScreenLifecycleEvent.Disappear, this)

dispatchTransitionProgress(1.0f, true)
}

Expand All @@ -215,20 +208,16 @@ open class ScreenFragment : Fragment {
}

private fun dispatchEventInChildContainers(event: ScreenLifecycleEvent) {
for (sc in mChildScreenContainers) {
if (sc.screenCount > 0) {
sc.topScreen?.let {
sc.topScreen?.fragment?.let { fragment -> dispatchEvent(event, fragment) }
}
}
mChildScreenContainers.filter { it.screenCount > 0 }.forEach {
it.topScreen?.fragment?.let { fragment -> dispatchEvent(event, fragment) }
}
}

fun dispatchHeaderBackButtonClickedEvent() {
val screenContext = screen.context as ReactContext
val eventDispatcher: EventDispatcher? =
UIManagerHelper.getEventDispatcherForReactTag(screenContext, screen.id)
eventDispatcher?.dispatchEvent(HeaderBackButtonClickedEvent(screen.id))
UIManagerHelper
.getEventDispatcherForReactTag(screenContext, screen.id)
?.dispatchEvent(HeaderBackButtonClickedEvent(screen.id))
}

fun dispatchTransitionProgress(alpha: Float, closing: Boolean) {
Expand All @@ -244,13 +233,13 @@ open class ScreenFragment : Fragment {
val container: ScreenContainer<*>? = screen.container
val goingForward = if (container is ScreenStack) container.goingForward else false
val screenContext = screen.context as ReactContext
val eventDispatcher: EventDispatcher? =
UIManagerHelper.getEventDispatcherForReactTag(screenContext, screen.id)
eventDispatcher?.dispatchEvent(
ScreenTransitionProgressEvent(
screen.id, mProgress, closing, goingForward, coalescingKey
UIManagerHelper
.getEventDispatcherForReactTag(screenContext, screen.id)
?.dispatchEvent(
ScreenTransitionProgressEvent(
screen.id, mProgress, closing, goingForward, coalescingKey
)
)
)
}
}
}
Expand Down Expand Up @@ -305,9 +294,9 @@ open class ScreenFragment : Fragment {
// we only send dismissed even when the screen has been removed from its container
val screenContext = screen.context
if (screenContext is ReactContext) {
val eventDispatcher: EventDispatcher? =
UIManagerHelper.getEventDispatcherForReactTag(screenContext, screen.id)
eventDispatcher?.dispatchEvent(ScreenDismissedEvent(screen.id))
UIManagerHelper
.getEventDispatcherForReactTag(screenContext, screen.id)
?.dispatchEvent(ScreenDismissedEvent(screen.id))
}
}
mChildScreenContainers.clear()
Expand Down
Loading

0 comments on commit 870007d

Please sign in to comment.