Skip to content
This repository was archived by the owner on Apr 18, 2021. It is now read-only.

Commit de7954b

Browse files
committed
support androidx fragment and appcompat.
1 parent b116a7c commit de7954b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+879
-9
lines changed

MainScope/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ dependencies {
2525
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
2626
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
2727

28+
compileOnly 'androidx.appcompat:appcompat:1.1.0'
29+
compileOnly 'androidx.recyclerview:recyclerview:1.1.0'
30+
2831
compileOnly "com.android.support:recyclerview-v7:$android_support_version"
2932
compileOnly "com.android.support:design:$android_support_version"
3033
compileOnly "com.android.support:appcompat-v7:$android_support_version"

MainScope/src/main/java/com/bennyhuo/kotlin/coroutines/android/mainscope/MainScope.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ interface MainScope: CoroutineScope{
2828
}
2929
}
3030

31+
val isAndroidXFragmentSupported by lazy {
32+
try {
33+
Class.forName("androidx.fragment.app.FragmentManager\$FragmentLifecycleCallbacks")
34+
Logcat.debug("AndroidX Fragment enabled.")
35+
true
36+
}catch (e: ClassNotFoundException){
37+
Logcat.debug("AndroidX Fragment disabled.")
38+
Logcat.error(e)
39+
false
40+
}
41+
}
42+
43+
3144
fun setUp(application: Application): Companion {
3245
application.registerActivityLifecycleCallbacks(ActivityLifecycleCallbackImpl)
3346
isSetUp = true
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package com.bennyhuo.kotlin.coroutines.android.mainscope.androidx
2+
3+
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope
4+
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch
5+
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.BasicScoped
6+
7+
interface AppCompatScoped: BasicScoped {
8+
fun androidx.appcompat.widget.ActionMenuView.onMenuItemClick(
9+
returnValue: Boolean = false,
10+
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit
11+
) {
12+
setOnMenuItemClickListener { item ->
13+
mainScope.launch {
14+
handler(item)
15+
}
16+
returnValue
17+
}
18+
}
19+
20+
fun androidx.appcompat.widget.ActivityChooserView.onDismiss(
21+
handler: suspend MainScope.() -> Unit
22+
) {
23+
setOnDismissListener { ->
24+
mainScope.launch(block = handler)
25+
}
26+
}
27+
28+
fun androidx.appcompat.widget.FitWindowsFrameLayout.onFitSystemWindows(
29+
handler: suspend MainScope.(insets: android.graphics.Rect?) -> Unit
30+
) {
31+
setOnFitSystemWindowsListener { insets ->
32+
mainScope.launch {
33+
handler(insets)
34+
}
35+
}
36+
}
37+
38+
fun androidx.appcompat.widget.SearchView.onClose(
39+
returnValue: Boolean = false,
40+
handler: suspend MainScope.() -> Unit
41+
) {
42+
setOnCloseListener { ->
43+
mainScope.launch(block = handler)
44+
returnValue
45+
}
46+
}
47+
48+
fun androidx.appcompat.widget.SearchView.onQueryTextFocusChange(
49+
handler: suspend MainScope.(v: android.view.View, hasFocus: Boolean) -> Unit
50+
) {
51+
setOnQueryTextFocusChangeListener { v, hasFocus ->
52+
mainScope.launch {
53+
handler(v, hasFocus)
54+
}
55+
}
56+
}
57+
58+
fun androidx.appcompat.widget.SearchView.onQueryTextListener(
59+
init: __SearchView_OnQueryTextListener.() -> Unit
60+
) {
61+
val listener = __SearchView_OnQueryTextListener(mainScope)
62+
listener.init()
63+
setOnQueryTextListener(listener)
64+
}
65+
66+
class __SearchView_OnQueryTextListener(private val mainScope: MainScope) : androidx.appcompat.widget.SearchView.OnQueryTextListener {
67+
68+
private var _onQueryTextSubmit: (suspend MainScope.(String?) -> Boolean)? = null
69+
private var _onQueryTextSubmit_returnValue: Boolean = false
70+
71+
override fun onQueryTextSubmit(query: String?) : Boolean {
72+
val returnValue = _onQueryTextSubmit_returnValue
73+
val handler = _onQueryTextSubmit ?: return returnValue
74+
mainScope.launch {
75+
handler(query)
76+
}
77+
return returnValue
78+
}
79+
80+
fun onQueryTextSubmit(
81+
returnValue: Boolean = false,
82+
listener: suspend MainScope.(String?) -> Boolean
83+
) {
84+
_onQueryTextSubmit = listener
85+
_onQueryTextSubmit_returnValue = returnValue
86+
}
87+
88+
private var _onQueryTextChange: (suspend MainScope.(String?) -> Boolean)? = null
89+
private var _onQueryTextChange_returnValue: Boolean = false
90+
91+
override fun onQueryTextChange(newText: String?) : Boolean {
92+
val returnValue = _onQueryTextChange_returnValue
93+
val handler = _onQueryTextChange ?: return returnValue
94+
mainScope.launch {
95+
handler(newText)
96+
}
97+
return returnValue
98+
}
99+
100+
fun onQueryTextChange(
101+
returnValue: Boolean = false,
102+
listener: suspend MainScope.(String?) -> Boolean
103+
) {
104+
_onQueryTextChange = listener
105+
_onQueryTextChange_returnValue = returnValue
106+
}
107+
108+
}fun androidx.appcompat.widget.SearchView.onSearchClick(
109+
handler: suspend MainScope.(v: android.view.View?) -> Unit
110+
) {
111+
setOnSearchClickListener { v ->
112+
mainScope.launch {
113+
handler(v)
114+
}
115+
}
116+
}
117+
118+
fun androidx.appcompat.widget.SearchView.onSuggestionListener(
119+
init: __SearchView_OnSuggestionListener.() -> Unit
120+
) {
121+
val listener = __SearchView_OnSuggestionListener(mainScope)
122+
listener.init()
123+
setOnSuggestionListener(listener)
124+
}
125+
126+
class __SearchView_OnSuggestionListener(private val mainScope: MainScope) : androidx.appcompat.widget.SearchView.OnSuggestionListener {
127+
128+
private var _onSuggestionSelect: (suspend MainScope.(Int) -> Boolean)? = null
129+
private var _onSuggestionSelect_returnValue: Boolean = false
130+
131+
override fun onSuggestionSelect(position: Int) : Boolean {
132+
val returnValue = _onSuggestionSelect_returnValue
133+
val handler = _onSuggestionSelect ?: return returnValue
134+
mainScope.launch {
135+
handler(position)
136+
}
137+
return returnValue
138+
}
139+
140+
fun onSuggestionSelect(
141+
returnValue: Boolean = false,
142+
listener: suspend MainScope.(Int) -> Boolean
143+
) {
144+
_onSuggestionSelect = listener
145+
_onSuggestionSelect_returnValue = returnValue
146+
}
147+
148+
private var _onSuggestionClick: (suspend MainScope.(Int) -> Boolean)? = null
149+
private var _onSuggestionClick_returnValue: Boolean = false
150+
151+
override fun onSuggestionClick(position: Int) : Boolean {
152+
val returnValue = _onSuggestionClick_returnValue
153+
val handler = _onSuggestionClick ?: return returnValue
154+
mainScope.launch {
155+
handler(position)
156+
}
157+
return returnValue
158+
}
159+
160+
fun onSuggestionClick(
161+
returnValue: Boolean = false,
162+
listener: suspend MainScope.(Int) -> Boolean
163+
) {
164+
_onSuggestionClick = listener
165+
_onSuggestionClick_returnValue = returnValue
166+
}
167+
168+
}fun androidx.appcompat.widget.Toolbar.onMenuItemClick(
169+
returnValue: Boolean = false,
170+
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit
171+
) {
172+
setOnMenuItemClickListener { item ->
173+
mainScope.launch {
174+
handler(item)
175+
}
176+
returnValue
177+
}
178+
}
179+
180+
fun androidx.appcompat.widget.ViewStubCompat.onInflate(
181+
handler: suspend MainScope.(stub: androidx.appcompat.widget.ViewStubCompat?, inflated: android.view.View?) -> Unit
182+
) {
183+
setOnInflateListener { stub, inflated ->
184+
mainScope.launch {
185+
handler(stub, inflated)
186+
}
187+
}
188+
}
189+
190+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.bennyhuo.kotlin.coroutines.android.mainscope.androidx
2+
3+
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope
4+
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch
5+
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.BasicScoped
6+
7+
interface RecyclerViewScoped: BasicScoped {
8+
9+
fun androidx.recyclerview.widget.RecyclerView.onChildAttachStateChangeListener(
10+
init: __RecyclerView_OnChildAttachStateChangeListener.() -> Unit
11+
) {
12+
val listener = __RecyclerView_OnChildAttachStateChangeListener(mainScope)
13+
listener.init()
14+
addOnChildAttachStateChangeListener(listener)
15+
}
16+
17+
class __RecyclerView_OnChildAttachStateChangeListener(private val mainScope: MainScope) : androidx.recyclerview.widget.RecyclerView.OnChildAttachStateChangeListener {
18+
19+
private var _onChildViewAttachedToWindow: (suspend MainScope.(android.view.View) -> Unit)? = null
20+
21+
22+
override fun onChildViewAttachedToWindow(view: android.view.View) {
23+
val handler = _onChildViewAttachedToWindow ?: return
24+
mainScope.launch {
25+
handler(view)
26+
}
27+
}
28+
29+
fun onChildViewAttachedToWindow(
30+
listener: suspend MainScope.(android.view.View) -> Unit
31+
) {
32+
_onChildViewAttachedToWindow = listener
33+
}
34+
35+
private var _onChildViewDetachedFromWindow: (suspend MainScope.(android.view.View) -> Unit)? = null
36+
37+
38+
override fun onChildViewDetachedFromWindow(view: android.view.View) {
39+
val handler = _onChildViewDetachedFromWindow ?: return
40+
mainScope.launch {
41+
handler(view)
42+
}
43+
}
44+
45+
fun onChildViewDetachedFromWindow(
46+
listener: suspend MainScope.(android.view.View) -> Unit
47+
) {
48+
_onChildViewDetachedFromWindow = listener
49+
}
50+
51+
}fun androidx.recyclerview.widget.RecyclerView.onItemTouchListener(
52+
init: __RecyclerView_OnItemTouchListener.() -> Unit
53+
) {
54+
val listener = __RecyclerView_OnItemTouchListener(mainScope)
55+
listener.init()
56+
addOnItemTouchListener(listener)
57+
}
58+
59+
class __RecyclerView_OnItemTouchListener(private val mainScope: MainScope) : androidx.recyclerview.widget.RecyclerView.OnItemTouchListener {
60+
61+
private var _onInterceptTouchEvent: (suspend MainScope.(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent) -> Boolean)? = null
62+
private var _onInterceptTouchEvent_returnValue: Boolean = false
63+
64+
override fun onInterceptTouchEvent(rv: androidx.recyclerview.widget.RecyclerView, e: android.view.MotionEvent) : Boolean {
65+
val returnValue = _onInterceptTouchEvent_returnValue
66+
val handler = _onInterceptTouchEvent ?: return returnValue
67+
mainScope.launch {
68+
handler(rv, e)
69+
}
70+
return returnValue
71+
}
72+
73+
fun onInterceptTouchEvent(
74+
returnValue: Boolean = false,
75+
listener: suspend MainScope.(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent) -> Boolean
76+
) {
77+
_onInterceptTouchEvent = listener
78+
_onInterceptTouchEvent_returnValue = returnValue
79+
}
80+
81+
private var _onTouchEvent: (suspend MainScope.(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent) -> Unit)? = null
82+
83+
84+
override fun onTouchEvent(rv: androidx.recyclerview.widget.RecyclerView, e: android.view.MotionEvent) {
85+
val handler = _onTouchEvent ?: return
86+
mainScope.launch {
87+
handler(rv, e)
88+
}
89+
}
90+
91+
fun onTouchEvent(
92+
listener: suspend MainScope.(androidx.recyclerview.widget.RecyclerView, android.view.MotionEvent) -> Unit
93+
) {
94+
_onTouchEvent = listener
95+
}
96+
97+
private var _onRequestDisallowInterceptTouchEvent: (suspend MainScope.(Boolean) -> Unit)? = null
98+
99+
100+
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
101+
val handler = _onRequestDisallowInterceptTouchEvent ?: return
102+
mainScope.launch {
103+
handler(disallowIntercept)
104+
}
105+
}
106+
107+
fun onRequestDisallowInterceptTouchEvent(
108+
listener: suspend MainScope.(Boolean) -> Unit
109+
) {
110+
_onRequestDisallowInterceptTouchEvent = listener
111+
}
112+
113+
}
114+
}

MainScope/src/main/java/com/bennyhuo/kotlin/coroutines/android/mainscope/internal/ActivityLifecycleCallbackImpl.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ internal object ActivityLifecycleCallbackImpl : Application.ActivityLifecycleCal
2525
(activity as? MainScoped)?.onMainScopeCreate()
2626
if (MainScope.isFragmentSupported) {
2727
(activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(FragmentLifecycleCallbackImpl, true)
28+
} else if (MainScope.isAndroidXFragmentSupported){ // androidx
29+
(activity as? androidx.fragment.app.FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(AndroidXFragmentLifecycleCallbackImpl, true)
2830
}
2931
}
3032

@@ -39,6 +41,15 @@ internal object ActivityLifecycleCallbackImpl : Application.ActivityLifecycleCal
3941
(fragment as? MainScoped)?.onMainScopeDestroy()
4042
}
4143
}
44+
} else if (MainScope.isAndroidXFragmentSupported){ // androidx
45+
Logcat.debug("onActivityDestroyed")
46+
(activity as? androidx.fragment.app.FragmentActivity)?.supportFragmentManager?.let { fragmentManager ->
47+
fragmentManager.unregisterFragmentLifecycleCallbacks(AndroidXFragmentLifecycleCallbackImpl)
48+
//Fragments may not be destroyed, so cancel scope right now.
49+
fragmentManager.fragments.forEach { fragment ->
50+
(fragment as? MainScoped)?.onMainScopeDestroy()
51+
}
52+
}
4253
}
4354
}
4455
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.bennyhuo.kotlin.coroutines.android.mainscope.internal
2+
3+
import android.os.Bundle
4+
import androidx.fragment.app.Fragment
5+
import androidx.fragment.app.FragmentManager
6+
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.MainScoped
7+
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeCreate
8+
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeDestroy
9+
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat
10+
11+
internal object AndroidXFragmentLifecycleCallbackImpl: FragmentManager.FragmentLifecycleCallbacks() {
12+
override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
13+
super.onFragmentCreated(fm, f, savedInstanceState)
14+
(f as? MainScoped)?.onMainScopeCreate()
15+
}
16+
17+
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
18+
super.onFragmentViewDestroyed(fm, f)
19+
Logcat.debug("onFragmentViewDestroyed")
20+
(f as? MainScoped)?.onMainScopeDestroy()
21+
}
22+
}

0 commit comments

Comments
 (0)