parent
e18f992930
commit
4d126dc274
@ -1,4 +1,4 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.autodisposable |
package com.android.base.utils.coroutines |
||||||
|
|
||||||
import android.os.Build |
import android.os.Build |
||||||
import android.view.View |
import android.view.View |
@ -1,4 +1,4 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.autodisposable |
package com.android.base.utils.coroutines |
||||||
|
|
||||||
import android.view.View |
import android.view.View |
||||||
import kotlinx.coroutines.* |
import kotlinx.coroutines.* |
@ -1,22 +0,0 @@ |
|||||||
*.iml |
|
||||||
.gradle |
|
||||||
/local.properties |
|
||||||
/.idea |
|
||||||
.DS_Store |
|
||||||
/build |
|
||||||
/captures |
|
||||||
.externalNativeBuild |
|
||||||
*.iml |
|
||||||
.idea/ |
|
||||||
.gradle |
|
||||||
/local.properties |
|
||||||
.DS_Store |
|
||||||
/build |
|
||||||
/captures |
|
||||||
*.apk |
|
||||||
*.ap_ |
|
||||||
*.dex |
|
||||||
*.class |
|
||||||
bin/ |
|
||||||
gen/ |
|
||||||
local.properties |
|
@ -1,3 +0,0 @@ |
|||||||
# Explanation |
|
||||||
|
|
||||||
modifying from [kotlin-coroutines-android](https://github.com/enbandari/kotlin-coroutines-android) to support AndroidX. |
|
@ -1,41 +0,0 @@ |
|||||||
apply plugin: 'com.android.library' |
|
||||||
apply plugin: 'kotlin-android' |
|
||||||
|
|
||||||
android { |
|
||||||
compileSdkVersion rootProject.compileSdkVersion |
|
||||||
buildToolsVersion rootProject.buildToolsVersion |
|
||||||
|
|
||||||
defaultConfig { |
|
||||||
minSdkVersion rootProject.minSdkVersion |
|
||||||
targetSdkVersion rootProject.targetSdkVersion |
|
||||||
versionCode 1 |
|
||||||
versionName "1.0" |
|
||||||
} |
|
||||||
|
|
||||||
kotlinOptions { |
|
||||||
jvmTarget = "1.8" |
|
||||||
} |
|
||||||
|
|
||||||
buildTypes { |
|
||||||
release { |
|
||||||
minifyEnabled false |
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
dependencies { |
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar']) |
|
||||||
|
|
||||||
//Kotlin |
|
||||||
api kotlinLibraries.kotlinStdlib |
|
||||||
api kotlinLibraries.kotlinReflect |
|
||||||
api kotlinLibraries.kotlinCoroutines |
|
||||||
api kotlinLibraries.kotlinAndroidCoroutines |
|
||||||
|
|
||||||
//AndroidX |
|
||||||
compileOnly androidLibraries.appcompat |
|
||||||
compileOnly androidLibraries.recyclerView |
|
||||||
compileOnly androidLibraries.material |
|
||||||
} |
|
@ -1,21 +0,0 @@ |
|||||||
# Add project specific ProGuard rules here. |
|
||||||
# You can control the set of applied configuration files using the |
|
||||||
# proguardFiles setting in build.gradle. |
|
||||||
# |
|
||||||
# For more details, see |
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html |
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following |
|
||||||
# and specify the fully qualified class name to the JavaScript interface |
|
||||||
# class: |
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
|
||||||
# public *; |
|
||||||
#} |
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for |
|
||||||
# debugging stack traces. |
|
||||||
#-keepattributes SourceFile,LineNumberTable |
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to |
|
||||||
# hide the original source file name. |
|
||||||
#-renamesourcefileattribute SourceFile |
|
@ -1,2 +0,0 @@ |
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
package="com.bennyhuo.kotlin.coroutines.android.mainscope"/> |
|
@ -1,50 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope |
|
||||||
|
|
||||||
import android.app.Application |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.internal.ActivityLifecycleCallbackImpl |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.EmptyInterceptor |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.EmptyJob |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.ImmutableCoroutineContext |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
|
||||||
import kotlinx.coroutines.CoroutineScope |
|
||||||
import kotlinx.coroutines.Dispatchers |
|
||||||
import kotlinx.coroutines.SupervisorJob |
|
||||||
import kotlin.coroutines.CoroutineContext |
|
||||||
|
|
||||||
interface MainScope : CoroutineScope { |
|
||||||
|
|
||||||
companion object { |
|
||||||
internal var isSetUp = false |
|
||||||
internal var isDebug = false |
|
||||||
|
|
||||||
val isFragmentSupported by lazy { |
|
||||||
try { |
|
||||||
Class.forName("androidx.fragment.app.FragmentManager\$FragmentLifecycleCallbacks") |
|
||||||
Logcat.debug("Fragment enabled.") |
|
||||||
true |
|
||||||
} catch (e: ClassNotFoundException) { |
|
||||||
Logcat.debug("Fragment disabled.") |
|
||||||
Logcat.error(e) |
|
||||||
false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun setUp(application: Application): Companion { |
|
||||||
application.registerActivityLifecycleCallbacks(ActivityLifecycleCallbackImpl) |
|
||||||
isSetUp = true |
|
||||||
return this |
|
||||||
} |
|
||||||
|
|
||||||
fun enableDebug() { |
|
||||||
isDebug = true |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal class MainScopeImpl : MainScope { |
|
||||||
override val coroutineContext = SupervisorJob() + Dispatchers.Main |
|
||||||
} |
|
||||||
|
|
||||||
internal object EmptyScope : MainScope { |
|
||||||
override val coroutineContext: CoroutineContext = ImmutableCoroutineContext(EmptyJob() + EmptyInterceptor) |
|
||||||
} |
|
@ -1,5 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.exception |
|
||||||
|
|
||||||
class UnsupportedTypeException(type: Class<*>, vararg supportedTypes: String) : Exception("Unsupported type: $type. ${supportedTypes.joinToString()} ${if (supportedTypes.size == 1) "is" else "are"} needed.") |
|
||||||
|
|
||||||
class UnsupportedVersionException(library: String, version: String) : Exception("Unsupported version: $version of $library") |
|
@ -1,46 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.internal |
|
||||||
|
|
||||||
import android.app.Activity |
|
||||||
import android.app.Application |
|
||||||
import android.os.Bundle |
|
||||||
import androidx.fragment.app.FragmentActivity |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.MainScoped |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeCreate |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeDestroy |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
|
||||||
|
|
||||||
internal object ActivityLifecycleCallbackImpl : Application.ActivityLifecycleCallbacks { |
|
||||||
|
|
||||||
override fun onActivityPaused(activity: Activity) {} |
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) {} |
|
||||||
|
|
||||||
override fun onActivityStarted(activity: Activity) {} |
|
||||||
|
|
||||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle?) {} |
|
||||||
|
|
||||||
override fun onActivityStopped(activity: Activity) {} |
|
||||||
|
|
||||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { |
|
||||||
(activity as? MainScoped)?.onMainScopeCreate() |
|
||||||
if (MainScope.isFragmentSupported) { |
|
||||||
(activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(FragmentLifecycleCallbackImpl, true) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityDestroyed(activity: Activity) { |
|
||||||
(activity as? MainScoped)?.onMainScopeDestroy() |
|
||||||
if (MainScope.isFragmentSupported) { |
|
||||||
Logcat.debug("onActivityDestroyed") |
|
||||||
(activity as? FragmentActivity)?.supportFragmentManager?.let { fragmentManager -> |
|
||||||
fragmentManager.unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbackImpl) |
|
||||||
//Fragments may not be destroyed, so cancel scope right now. |
|
||||||
fragmentManager.fragments.forEach { fragment -> |
|
||||||
(fragment as? MainScoped)?.onMainScopeDestroy() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,24 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.internal |
|
||||||
|
|
||||||
import android.os.Bundle |
|
||||||
import androidx.fragment.app.Fragment |
|
||||||
import androidx.fragment.app.FragmentManager |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.MainScoped |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeCreate |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeDestroy |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
|
||||||
|
|
||||||
internal object FragmentLifecycleCallbackImpl: FragmentManager.FragmentLifecycleCallbacks() { |
|
||||||
|
|
||||||
override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { |
|
||||||
super.onFragmentCreated(fm, f, savedInstanceState) |
|
||||||
(f as? MainScoped)?.onMainScopeCreate() |
|
||||||
} |
|
||||||
|
|
||||||
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) { |
|
||||||
super.onFragmentViewDestroyed(fm, f) |
|
||||||
Logcat.debug("onFragmentViewDestroyed") |
|
||||||
(f as? MainScoped)?.onMainScopeDestroy() |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,21 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
|
||||||
|
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import kotlinx.coroutines.CoroutineStart |
|
||||||
import kotlinx.coroutines.Job |
|
||||||
import kotlinx.coroutines.newCoroutineContext |
|
||||||
import kotlin.coroutines.CoroutineContext |
|
||||||
import kotlin.coroutines.EmptyCoroutineContext |
|
||||||
import kotlinx.coroutines.launch as launchInternal |
|
||||||
|
|
||||||
|
|
||||||
internal fun MainScope.launch( |
|
||||||
context: CoroutineContext = EmptyCoroutineContext, |
|
||||||
start: CoroutineStart = CoroutineStart.DEFAULT, |
|
||||||
block: suspend MainScope.() -> Unit |
|
||||||
): Job { |
|
||||||
val newContext = newCoroutineContext(context) |
|
||||||
val coroutine = StandaloneCoroutineCompat(newContext, true) |
|
||||||
coroutine.start(start, coroutine, block) |
|
||||||
return coroutine |
|
||||||
} |
|
@ -1,7 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
|
||||||
|
|
||||||
import kotlinx.coroutines.DisposableHandle |
|
||||||
|
|
||||||
object EmptyDisposableHandle: DisposableHandle { |
|
||||||
override fun dispose() = Unit |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
|
||||||
|
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
|
||||||
import kotlin.coroutines.* |
|
||||||
|
|
||||||
internal object EmptyInterceptor: ContinuationInterceptor, AbstractCoroutineContextElement(ContinuationInterceptor) { |
|
||||||
|
|
||||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> { |
|
||||||
return EmptyContinuation as Continuation<T> |
|
||||||
} |
|
||||||
|
|
||||||
private object EmptyContinuation: Continuation<Any>{ |
|
||||||
override val context: CoroutineContext = EmptyCoroutineContext |
|
||||||
|
|
||||||
override fun resumeWith(result: Result<Any>) { |
|
||||||
Logcat.warn("Intercepted coroutine. won't resume.") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,63 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
|
||||||
|
|
||||||
import kotlinx.coroutines.CancellationException |
|
||||||
import kotlinx.coroutines.CompletionHandler |
|
||||||
import kotlinx.coroutines.InternalCoroutinesApi |
|
||||||
import kotlinx.coroutines.Job |
|
||||||
import kotlinx.coroutines.selects.SelectClause0 |
|
||||||
import kotlinx.coroutines.selects.SelectInstance |
|
||||||
import kotlin.coroutines.CoroutineContext |
|
||||||
import kotlin.coroutines.CoroutineContext.Element |
|
||||||
import kotlin.coroutines.CoroutineContext.Key |
|
||||||
import kotlin.coroutines.EmptyCoroutineContext |
|
||||||
|
|
||||||
internal class EmptyJob : JobCompat(), SelectClause0 { |
|
||||||
|
|
||||||
private val cancellationException = CancellationException("EmptyScope") |
|
||||||
|
|
||||||
override val children: Sequence<Job> = emptySequence() |
|
||||||
|
|
||||||
override val isActive: Boolean = false |
|
||||||
|
|
||||||
override val isCancelled: Boolean = true |
|
||||||
|
|
||||||
override val isCompleted: Boolean = true |
|
||||||
|
|
||||||
override val key: Key<*> = Job |
|
||||||
|
|
||||||
override val onJoin: SelectClause0 = this |
|
||||||
|
|
||||||
@InternalCoroutinesApi |
|
||||||
override fun <R> registerSelectClause0(select: SelectInstance<R>, block: suspend () -> R) = Unit |
|
||||||
|
|
||||||
override fun cancel(cause: Throwable?) = false |
|
||||||
|
|
||||||
override fun cancel(cause: CancellationException?) = Unit |
|
||||||
|
|
||||||
@InternalCoroutinesApi |
|
||||||
override fun getCancellationException() = cancellationException |
|
||||||
|
|
||||||
@InternalCoroutinesApi |
|
||||||
override fun invokeOnCompletion(onCancelling: Boolean, invokeImmediately: Boolean, handler: CompletionHandler) = EmptyDisposableHandle.also { handler.invoke(cancellationException) } |
|
||||||
|
|
||||||
override fun invokeOnCompletion(handler: CompletionHandler) = EmptyDisposableHandle.also { handler.invoke(cancellationException) } |
|
||||||
|
|
||||||
override suspend fun join() = Unit |
|
||||||
|
|
||||||
override fun start() = false |
|
||||||
|
|
||||||
override fun plus(other: Job): Job = this |
|
||||||
|
|
||||||
override fun cancel() = Unit |
|
||||||
|
|
||||||
//region solutions for AbstractMethodError. |
|
||||||
override operator fun <E : Element> get(key: Key<E>): E? = |
|
||||||
if (this.key == key) this as E else null |
|
||||||
|
|
||||||
override fun <R> fold(initial: R, operation: (R, Element) -> R): R = operation(initial, this) |
|
||||||
|
|
||||||
override fun minusKey(key: Key<*>): CoroutineContext = |
|
||||||
if (this.key == key) EmptyCoroutineContext else this |
|
||||||
//endregion |
|
||||||
|
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
|
||||||
|
|
||||||
import kotlin.coroutines.CoroutineContext |
|
||||||
import kotlin.coroutines.CoroutineContext.Element |
|
||||||
import kotlin.coroutines.CoroutineContext.Key |
|
||||||
|
|
||||||
class ImmutableCoroutineContext(private val coroutineContext: CoroutineContext): CoroutineContext { |
|
||||||
override fun <R> fold(initial: R, operation: (R, Element) -> R): R = coroutineContext.fold(initial, operation) |
|
||||||
|
|
||||||
override fun <E : Element> get(key: Key<E>) = coroutineContext[key] |
|
||||||
|
|
||||||
override fun minusKey(key: Key<*>) = this |
|
||||||
|
|
||||||
override fun plus(context: CoroutineContext) = this |
|
||||||
} |
|
@ -1,37 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job; |
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull; |
|
||||||
|
|
||||||
import kotlin.coroutines.CoroutineContext; |
|
||||||
import kotlinx.coroutines.ChildHandle; |
|
||||||
import kotlinx.coroutines.ChildJob; |
|
||||||
import kotlinx.coroutines.Job; |
|
||||||
|
|
||||||
abstract class JobCompat implements Job { |
|
||||||
@NotNull |
|
||||||
@Override |
|
||||||
public final ChildHandle attachChild(@NotNull ChildJob childJob) { |
|
||||||
//Parent is already cancelled. So cancel child directly.
|
|
||||||
childJob.cancel(getCancellationException()); |
|
||||||
return EmptyChildHandle.instance; |
|
||||||
} |
|
||||||
|
|
||||||
private static class EmptyChildHandle implements ChildHandle { |
|
||||||
private static final EmptyChildHandle instance = new EmptyChildHandle(); |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean childCancelled(@NotNull Throwable throwable) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void dispose() { } |
|
||||||
} |
|
||||||
|
|
||||||
//solutions for AbstractMethodError.
|
|
||||||
@NotNull |
|
||||||
@Override |
|
||||||
public final CoroutineContext plus(@NotNull CoroutineContext coroutineContext) { |
|
||||||
return CoroutineContext.DefaultImpls.plus(this, coroutineContext); |
|
||||||
} |
|
||||||
} |
|
@ -1,22 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job; |
|
||||||
|
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope; |
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull; |
|
||||||
|
|
||||||
import kotlin.Unit; |
|
||||||
import kotlin.coroutines.CoroutineContext; |
|
||||||
import kotlinx.coroutines.AbstractCoroutine; |
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandlerKt; |
|
||||||
|
|
||||||
class StandaloneCoroutineCompat extends AbstractCoroutine<Unit> implements MainScope { |
|
||||||
public StandaloneCoroutineCompat(@NotNull CoroutineContext parentContext, boolean active) { |
|
||||||
super(parentContext, active); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected boolean handleJobException(@NotNull Throwable exception) { |
|
||||||
CoroutineExceptionHandlerKt.handleCoroutineException(getContext(), exception); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
@ -1,195 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
|
||||||
|
|
||||||
import androidx.appcompat.widget.* |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
|
||||||
|
|
||||||
interface AppCompatScoped : BasicScoped { |
|
||||||
|
|
||||||
fun ActionMenuView.onMenuItemClick( |
|
||||||
returnValue: Boolean = false, |
|
||||||
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit |
|
||||||
) { |
|
||||||
setOnMenuItemClickListener { item -> |
|
||||||
mainScope.launch { |
|
||||||
handler(item) |
|
||||||
} |
|
||||||
returnValue |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun ActivityChooserView.onDismiss( |
|
||||||
handler: suspend MainScope.() -> Unit |
|
||||||
) { |
|
||||||
setOnDismissListener { -> |
|
||||||
mainScope.launch(block = handler) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun FitWindowsFrameLayout.onFitSystemWindows( |
|
||||||
handler: suspend MainScope.(insets: android.graphics.Rect?) -> Unit |
|
||||||
) { |
|
||||||
setOnFitSystemWindowsListener { insets -> |
|
||||||
mainScope.launch { |
|
||||||
handler(insets) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun SearchView.onClose( |
|
||||||
returnValue: Boolean = false, |
|
||||||
handler: suspend MainScope.() -> Unit |
|
||||||
) { |
|
||||||
setOnCloseListener { -> |
|
||||||
mainScope.launch(block = handler) |
|
||||||
returnValue |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun SearchView.onQueryTextFocusChange( |
|
||||||
handler: suspend MainScope.(v: android.view.View, hasFocus: Boolean) -> Unit |
|
||||||
) { |
|
||||||
setOnQueryTextFocusChangeListener { v, hasFocus -> |
|
||||||
mainScope.launch { |
|
||||||
handler(v, hasFocus) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun SearchView.onQueryTextListener( |
|
||||||
init: __SearchView_OnQueryTextListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __SearchView_OnQueryTextListener(mainScope) |
|
||||||
listener.init() |
|
||||||
setOnQueryTextListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __SearchView_OnQueryTextListener(private val mainScope: MainScope) : SearchView.OnQueryTextListener { |
|
||||||
|
|
||||||
private var _onQueryTextSubmit: (suspend MainScope.(String?) -> Boolean)? = null |
|
||||||
private var _onQueryTextSubmit_returnValue: Boolean = false |
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: String?): Boolean { |
|
||||||
val returnValue = _onQueryTextSubmit_returnValue |
|
||||||
val handler = _onQueryTextSubmit ?: return returnValue |
|
||||||
mainScope.launch { |
|
||||||
handler(query) |
|
||||||
} |
|
||||||
return returnValue |
|
||||||
} |
|
||||||
|
|
||||||
fun onQueryTextSubmit( |
|
||||||
returnValue: Boolean = false, |
|
||||||
listener: suspend MainScope.(String?) -> Boolean |
|
||||||
) { |
|
||||||
_onQueryTextSubmit = listener |
|
||||||
_onQueryTextSubmit_returnValue = returnValue |
|
||||||
} |
|
||||||
|
|
||||||
private var _onQueryTextChange: (suspend MainScope.(String?) -> Boolean)? = null |
|
||||||
private var _onQueryTextChange_returnValue: Boolean = false |
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String?): Boolean { |
|
||||||
val returnValue = _onQueryTextChange_returnValue |
|
||||||
val handler = _onQueryTextChange ?: return returnValue |
|
||||||
mainScope.launch { |
|
||||||
handler(newText) |
|
||||||
} |
|
||||||
return returnValue |
|
||||||
} |
|
||||||
|
|
||||||
fun onQueryTextChange( |
|
||||||
returnValue: Boolean = false, |
|
||||||
listener: suspend MainScope.(String?) -> Boolean |
|
||||||
) { |
|
||||||
_onQueryTextChange = listener |
|
||||||
_onQueryTextChange_returnValue = returnValue |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun SearchView.onSearchClick( |
|
||||||
handler: suspend MainScope.(v: android.view.View?) -> Unit |
|
||||||
) { |
|
||||||
setOnSearchClickListener { v -> |
|
||||||
mainScope.launch { |
|
||||||
handler(v) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun SearchView.onSuggestionListener( |
|
||||||
init: __SearchView_OnSuggestionListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __SearchView_OnSuggestionListener(mainScope) |
|
||||||
listener.init() |
|
||||||
setOnSuggestionListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __SearchView_OnSuggestionListener(private val mainScope: MainScope) : SearchView.OnSuggestionListener { |
|
||||||
|
|
||||||
private var _onSuggestionSelect: (suspend MainScope.(Int) -> Boolean)? = null |
|
||||||
private var _onSuggestionSelect_returnValue: Boolean = false |
|
||||||
|
|
||||||
override fun onSuggestionSelect(position: Int): Boolean { |
|
||||||
val returnValue = _onSuggestionSelect_returnValue |
|
||||||
val handler = _onSuggestionSelect ?: return returnValue |
|
||||||
mainScope.launch { |
|
||||||
handler(position) |
|
||||||
} |
|
||||||
return returnValue |
|
||||||
} |
|
||||||
|
|
||||||
fun onSuggestionSelect( |
|
||||||
returnValue: Boolean = false, |
|
||||||
listener: suspend MainScope.(Int) -> Boolean |
|
||||||
) { |
|
||||||
_onSuggestionSelect = listener |
|
||||||
_onSuggestionSelect_returnValue = returnValue |
|
||||||
} |
|
||||||
|
|
||||||
private var _onSuggestionClick: (suspend MainScope.(Int) -> Boolean)? = null |
|
||||||
private var _onSuggestionClick_returnValue: Boolean = false |
|
||||||
|
|
||||||
override fun onSuggestionClick(position: Int): Boolean { |
|
||||||
val returnValue = _onSuggestionClick_returnValue |
|
||||||
val handler = _onSuggestionClick ?: return returnValue |
|
||||||
mainScope.launch { |
|
||||||
handler(position) |
|
||||||
} |
|
||||||
return returnValue |
|
||||||
} |
|
||||||
|
|
||||||
fun onSuggestionClick( |
|
||||||
returnValue: Boolean = false, |
|
||||||
listener: suspend MainScope.(Int) -> Boolean |
|
||||||
) { |
|
||||||
_onSuggestionClick = listener |
|
||||||
_onSuggestionClick_returnValue = returnValue |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun Toolbar.onMenuItemClick( |
|
||||||
returnValue: Boolean = false, |
|
||||||
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit |
|
||||||
) { |
|
||||||
setOnMenuItemClickListener { item -> |
|
||||||
mainScope.launch { |
|
||||||
handler(item) |
|
||||||
} |
|
||||||
returnValue |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun ViewStubCompat.onInflate( |
|
||||||
handler: suspend MainScope.(stub: ViewStubCompat?, inflated: android.view.View?) -> Unit |
|
||||||
) { |
|
||||||
setOnInflateListener { stub, inflated -> |
|
||||||
mainScope.launch { |
|
||||||
handler(stub, inflated) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -1,369 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
|
||||||
|
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
|
||||||
import com.google.android.material.appbar.AppBarLayout |
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView |
|
||||||
import com.google.android.material.chip.ChipGroup |
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton |
|
||||||
import com.google.android.material.tabs.TabLayout |
|
||||||
|
|
||||||
interface DesignScoped : BasicScoped { |
|
||||||
|
|
||||||
fun AppBarLayout.onOffsetChanged( |
|
||||||
handler: suspend MainScope.(appBarLayout: AppBarLayout?, verticalOffset: Int) -> Unit |
|
||||||
) { |
|
||||||
addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> |
|
||||||
mainScope.launch { |
|
||||||
handler(appBarLayout, verticalOffset) |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fun <T : TabLayout.Tab> TabLayout.onTabSelectedListener( |
|
||||||
init: __onTabSelected_TabLayout_BaseOnTabSelectedListener<T>.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __onTabSelected_TabLayout_BaseOnTabSelectedListener<T>(mainScope) |
|
||||||
listener.init() |
|
||||||
addOnTabSelectedListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __onTabSelected_TabLayout_BaseOnTabSelectedListener<T : TabLayout.Tab>(private val mainScope: MainScope) : TabLayout.BaseOnTabSelectedListener<T> { |
|
||||||
|
|
||||||
private var _onTabSelectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onTabSelected(p0: T?) { |
|
||||||
val handler = _onTabSelectedWithP0 ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(p0) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onTabSelected( |
|
||||||
listener: suspend MainScope.(T?) -> Unit |
|
||||||
) { |
|
||||||
_onTabSelectedWithP0 = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onTabUnselectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onTabUnselected(p0: T?) { |
|
||||||
val handler = _onTabUnselectedWithP0 ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(p0) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onTabUnselected( |
|
||||||
listener: suspend MainScope.(T?) -> Unit |
|
||||||
) { |
|
||||||
_onTabUnselectedWithP0 = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onTabReselectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onTabReselected(p0: T?) { |
|
||||||
val handler = _onTabReselectedWithP0 ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(p0) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onTabReselected( |
|
||||||
listener: suspend MainScope.(T?) -> Unit |
|
||||||
) { |
|
||||||
_onTabReselectedWithP0 = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun FloatingActionButton.onShowAnimationListener( |
|
||||||
init: __onShowAnimation_Animator_AnimatorListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __onShowAnimation_Animator_AnimatorListener(mainScope) |
|
||||||
listener.init() |
|
||||||
addOnShowAnimationListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __onShowAnimation_Animator_AnimatorListener(private val mainScope: MainScope) : android.animation.Animator.AnimatorListener { |
|
||||||
|
|
||||||
private var _onAnimationStartWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onAnimationStart(animation: android.animation.Animator?, isReverse: Boolean) { |
|
||||||
val handler = _onAnimationStartWithAnimationAndIsReverse ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation, isReverse) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationStart( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationStartWithAnimationAndIsReverse = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationEndWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: android.animation.Animator?, isReverse: Boolean) { |
|
||||||
val handler = _onAnimationEndWithAnimationAndIsReverse ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation, isReverse) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationEnd( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationEndWithAnimationAndIsReverse = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationStartWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationStart(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationStartWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationStart( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationStartWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationEndWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationEndWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationEnd( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationEndWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationCancelWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationCancel(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationCancelWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationCancel( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationCancelWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationRepeatWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationRepeat(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationRepeatWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationRepeat( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationRepeatWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun FloatingActionButton.onHideAnimationListener( |
|
||||||
init: __onHideAnimation_Animator_AnimatorListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __onHideAnimation_Animator_AnimatorListener(mainScope) |
|
||||||
listener.init() |
|
||||||
addOnHideAnimationListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __onHideAnimation_Animator_AnimatorListener(private val mainScope: MainScope) : android.animation.Animator.AnimatorListener { |
|
||||||
|
|
||||||
private var _onAnimationStartWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationStart(animation: android.animation.Animator?, isReverse: Boolean) { |
|
||||||
val handler = _onAnimationStartWithAnimationAndIsReverse ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation, isReverse) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationStart( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationStartWithAnimationAndIsReverse = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationEndWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: android.animation.Animator?, isReverse: Boolean) { |
|
||||||
val handler = _onAnimationEndWithAnimationAndIsReverse ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation, isReverse) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationEnd( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationEndWithAnimationAndIsReverse = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationStartWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationStart(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationStartWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationStart( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationStartWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationEndWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationEndWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationEnd( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationEndWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationCancelWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationCancel(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationCancelWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationCancel( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationCancelWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onAnimationRepeatWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onAnimationRepeat(animation: android.animation.Animator?) { |
|
||||||
val handler = _onAnimationRepeatWithAnimation ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(animation) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onAnimationRepeat( |
|
||||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
|
||||||
) { |
|
||||||
_onAnimationRepeatWithAnimation = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun ChipGroup.onCheckedChange( |
|
||||||
handler: suspend MainScope.(p0: ChipGroup?, p1: Int) -> Unit |
|
||||||
) { |
|
||||||
setOnCheckedChangeListener { p0, p1 -> |
|
||||||
mainScope.launch { |
|
||||||
handler(p0, p1) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun ChipGroup.onHierarchyChangeListener( |
|
||||||
init: __onHierarchyChange_ViewGroup_OnHierarchyChangeListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __onHierarchyChange_ViewGroup_OnHierarchyChangeListener(mainScope) |
|
||||||
listener.init() |
|
||||||
setOnHierarchyChangeListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __onHierarchyChange_ViewGroup_OnHierarchyChangeListener(private val mainScope: MainScope) : android.view.ViewGroup.OnHierarchyChangeListener { |
|
||||||
|
|
||||||
private var _onChildViewAddedWithParentAndChild: (suspend MainScope.(android.view.View?, android.view.View?) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onChildViewAdded(parent: android.view.View?, child: android.view.View?) { |
|
||||||
val handler = _onChildViewAddedWithParentAndChild ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(parent, child) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onChildViewAdded( |
|
||||||
listener: suspend MainScope.(android.view.View?, android.view.View?) -> Unit |
|
||||||
) { |
|
||||||
_onChildViewAddedWithParentAndChild = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onChildViewRemovedWithParentAndChild: (suspend MainScope.(android.view.View?, android.view.View?) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onChildViewRemoved(parent: android.view.View?, child: android.view.View?) { |
|
||||||
val handler = _onChildViewRemovedWithParentAndChild ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(parent, child) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onChildViewRemoved( |
|
||||||
listener: suspend MainScope.(android.view.View?, android.view.View?) -> Unit |
|
||||||
) { |
|
||||||
_onChildViewRemovedWithParentAndChild = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun BottomNavigationView.onNavigationItemReselected( |
|
||||||
handler: suspend MainScope.(item: android.view.MenuItem) -> Unit |
|
||||||
) { |
|
||||||
setOnNavigationItemReselectedListener { item -> |
|
||||||
mainScope.launch { |
|
||||||
handler(item) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun BottomNavigationView.onNavigationItemSelected( |
|
||||||
returnValue: Boolean = false, |
|
||||||
handler: suspend MainScope.(item: android.view.MenuItem) -> Unit |
|
||||||
) { |
|
||||||
setOnNavigationItemSelectedListener { item -> |
|
||||||
mainScope.launch { |
|
||||||
handler(item) |
|
||||||
} |
|
||||||
returnValue |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,73 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
|
||||||
|
|
||||||
import android.app.Activity |
|
||||||
import android.os.Looper |
|
||||||
import androidx.fragment.app.Fragment |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.EmptyScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScopeImpl |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.exception.UnsupportedTypeException |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.exception.UnsupportedVersionException |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
|
||||||
import kotlinx.coroutines.cancel |
|
||||||
import java.util.* |
|
||||||
|
|
||||||
interface MainScoped { |
|
||||||
|
|
||||||
companion object { |
|
||||||
internal val scopeMap = IdentityHashMap<MainScoped, MainScope>() |
|
||||||
} |
|
||||||
|
|
||||||
val mainScope: MainScope |
|
||||||
get() { |
|
||||||
if(!MainScope.isSetUp){ |
|
||||||
throw IllegalStateException("MainScope has not been set up yet! Call `MainScope.setUp(application)` once your customized Application created.") |
|
||||||
} |
|
||||||
if(Thread.currentThread() != Looper.getMainLooper().thread){ |
|
||||||
throw IllegalAccessException("MainScope must be accessed from the UI main thread.") |
|
||||||
} |
|
||||||
return (scopeMap[this]) ?: run { |
|
||||||
if(isDestroyed()){ |
|
||||||
Logcat.debug("Access MainScope when scoped instance:$this is FINISHING. EmptyScope will be returned.") |
|
||||||
EmptyScope |
|
||||||
} else { |
|
||||||
Logcat.warn("Create MainScope for scoped instance: $this") |
|
||||||
MainScopeImpl().also { scopeMap[this] = it } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private fun MainScoped.isDestroyed(): Boolean { |
|
||||||
return when{ |
|
||||||
this is Activity ->{ |
|
||||||
this.isFinishing |
|
||||||
} |
|
||||||
MainScope.isFragmentSupported && this is Fragment ->{ |
|
||||||
this.activity?.isFinishing?: true || this.isRemoving ||this.view == null |
|
||||||
} |
|
||||||
else ->{ |
|
||||||
val fragmentClass = try { |
|
||||||
Class.forName("android.support.v4.app.Fragment") |
|
||||||
} catch (e: Exception) { |
|
||||||
null |
|
||||||
} |
|
||||||
fragmentClass?.let { |
|
||||||
if(it.isAssignableFrom(this.javaClass)){ |
|
||||||
throw UnsupportedVersionException("com.android.support:support-fragment", "<25.1.0") |
|
||||||
} |
|
||||||
} |
|
||||||
throw UnsupportedTypeException(this.javaClass, "android.app.Activity", "android.support.v4.app.Fragment") |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
inline fun <T> MainScoped.withMainScope(block: MainScope.() -> T) = with(mainScope, block) |
|
||||||
|
|
||||||
internal fun MainScoped.onMainScopeCreate() { |
|
||||||
//won't create immediately. |
|
||||||
} |
|
||||||
|
|
||||||
internal fun MainScoped.onMainScopeDestroy() { |
|
||||||
MainScoped.scopeMap.remove(this)?.cancel() |
|
||||||
} |
|
@ -1,115 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
|
||||||
|
|
||||||
interface RecyclerViewScoped : BasicScoped { |
|
||||||
|
|
||||||
fun RecyclerView.onChildAttachStateChangeListener( |
|
||||||
init: __RecyclerView_OnChildAttachStateChangeListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __RecyclerView_OnChildAttachStateChangeListener(mainScope) |
|
||||||
listener.init() |
|
||||||
addOnChildAttachStateChangeListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __RecyclerView_OnChildAttachStateChangeListener(private val mainScope: MainScope) : RecyclerView.OnChildAttachStateChangeListener { |
|
||||||
|
|
||||||
private var _onChildViewAttachedToWindow: (suspend MainScope.(android.view.View) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onChildViewAttachedToWindow(view: android.view.View) { |
|
||||||
val handler = _onChildViewAttachedToWindow ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(view) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onChildViewAttachedToWindow( |
|
||||||
listener: suspend MainScope.(android.view.View) -> Unit |
|
||||||
) { |
|
||||||
_onChildViewAttachedToWindow = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onChildViewDetachedFromWindow: (suspend MainScope.(android.view.View) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onChildViewDetachedFromWindow(view: android.view.View) { |
|
||||||
val handler = _onChildViewDetachedFromWindow ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(view) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onChildViewDetachedFromWindow( |
|
||||||
listener: suspend MainScope.(android.view.View) -> Unit |
|
||||||
) { |
|
||||||
_onChildViewDetachedFromWindow = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
fun RecyclerView.onItemTouchListener( |
|
||||||
init: __RecyclerView_OnItemTouchListener.() -> Unit |
|
||||||
) { |
|
||||||
val listener = __RecyclerView_OnItemTouchListener(mainScope) |
|
||||||
listener.init() |
|
||||||
addOnItemTouchListener(listener) |
|
||||||
} |
|
||||||
|
|
||||||
class __RecyclerView_OnItemTouchListener(private val mainScope: MainScope) : RecyclerView.OnItemTouchListener { |
|
||||||
|
|
||||||
private var _onInterceptTouchEvent: (suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Boolean)? = null |
|
||||||
private var _onInterceptTouchEvent_returnValue: Boolean = false |
|
||||||
|
|
||||||
override fun onInterceptTouchEvent(rv: RecyclerView, e: android.view.MotionEvent): Boolean { |
|
||||||
val returnValue = _onInterceptTouchEvent_returnValue |
|
||||||
val handler = _onInterceptTouchEvent ?: return returnValue |
|
||||||
mainScope.launch { |
|
||||||
handler(rv, e) |
|
||||||
} |
|
||||||
return returnValue |
|
||||||
} |
|
||||||
|
|
||||||
fun onInterceptTouchEvent( |
|
||||||
returnValue: Boolean = false, |
|
||||||
listener: suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Boolean |
|
||||||
) { |
|
||||||
_onInterceptTouchEvent = listener |
|
||||||
_onInterceptTouchEvent_returnValue = returnValue |
|
||||||
} |
|
||||||
|
|
||||||
private var _onTouchEvent: (suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Unit)? = null |
|
||||||
|
|
||||||
override fun onTouchEvent(rv: RecyclerView, e: android.view.MotionEvent) { |
|
||||||
val handler = _onTouchEvent ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(rv, e) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onTouchEvent( |
|
||||||
listener: suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Unit |
|
||||||
) { |
|
||||||
_onTouchEvent = listener |
|
||||||
} |
|
||||||
|
|
||||||
private var _onRequestDisallowInterceptTouchEvent: (suspend MainScope.(Boolean) -> Unit)? = null |
|
||||||
|
|
||||||
|
|
||||||
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) { |
|
||||||
val handler = _onRequestDisallowInterceptTouchEvent ?: return |
|
||||||
mainScope.launch { |
|
||||||
handler(disallowIntercept) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun onRequestDisallowInterceptTouchEvent( |
|
||||||
listener: suspend MainScope.(Boolean) -> Unit |
|
||||||
) { |
|
||||||
_onRequestDisallowInterceptTouchEvent = listener |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,22 +0,0 @@ |
|||||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.utils |
|
||||||
|
|
||||||
import android.util.Log |
|
||||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
|
||||||
|
|
||||||
object Logcat { |
|
||||||
|
|
||||||
private const val TAG = "MainScope" |
|
||||||
|
|
||||||
fun debug(log: Any?) = MainScope.isDebug.whenTrue { Log.d(TAG, log.toString()) } |
|
||||||
|
|
||||||
fun warn(log: Any?) = MainScope.isDebug.whenTrue { Log.w(TAG, log.toString()) } |
|
||||||
|
|
||||||
fun error(log: Any?) = MainScope.isDebug.whenTrue { Log.e(TAG, log.toString()) } |
|
||||||
|
|
||||||
private fun Boolean.whenTrue(block: () -> Unit) { |
|
||||||
if (this) { |
|
||||||
block() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue