forked from CeuiLiSA/Pixiv-Shaft
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
LoxiaLiSA
committed
Mar 6, 2024
1 parent
ca7ecdc
commit b46aa0a
Showing
10 changed files
with
171 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package ceui.loxia | ||
|
||
import androidx.annotation.MainThread | ||
import androidx.fragment.app.Fragment | ||
import androidx.lifecycle.HasDefaultViewModelProviderFactory | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.ViewModelProvider | ||
import androidx.lifecycle.ViewModelStore | ||
import androidx.lifecycle.ViewModelStoreOwner | ||
import androidx.lifecycle.viewmodel.CreationExtras | ||
import kotlin.reflect.KClass | ||
|
||
|
||
|
||
@MainThread | ||
public inline fun <reified VM : ViewModel> Fragment.keyedViewModels( | ||
noinline keyPrefixProvider: ()->String, | ||
noinline ownerProducer: () -> ViewModelStoreOwner = { this }, | ||
noinline extrasProducer: (() -> CreationExtras)? = null, | ||
noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null | ||
): Lazy<VM> { | ||
val owner by lazy(LazyThreadSafetyMode.NONE) { ownerProducer() } | ||
return keyedCreateViewModelLazy( | ||
keyPrefixProvider, | ||
VM::class, | ||
{ owner.viewModelStore }, | ||
{ | ||
extrasProducer?.invoke() | ||
?: (owner as? HasDefaultViewModelProviderFactory)?.defaultViewModelCreationExtras | ||
?: CreationExtras.Empty | ||
}, | ||
factoryProducer ?: { | ||
(owner as? HasDefaultViewModelProviderFactory)?.defaultViewModelProviderFactory | ||
?: defaultViewModelProviderFactory | ||
}) | ||
} | ||
|
||
@MainThread | ||
public fun <VM : ViewModel> Fragment.keyedCreateViewModelLazy( | ||
keyPrefixProvider: ()->String, | ||
viewModelClass: KClass<VM>, | ||
storeProducer: () -> ViewModelStore, | ||
extrasProducer: () -> CreationExtras = { defaultViewModelCreationExtras }, | ||
factoryProducer: (() -> ViewModelProvider.Factory)? = null | ||
|
||
): Lazy<VM> { | ||
val factoryPromise = factoryProducer ?: { | ||
defaultViewModelProviderFactory | ||
} | ||
return KeyedViewModelLazy(keyPrefixProvider, viewModelClass, storeProducer, factoryPromise, extrasProducer) | ||
} | ||
|
||
public class KeyedViewModelLazy<VM : ViewModel> @JvmOverloads constructor( | ||
private val keyPrefixProvider: ()->String, | ||
private val viewModelClass: KClass<VM>, | ||
private val storeProducer: () -> ViewModelStore, | ||
private val factoryProducer: () -> ViewModelProvider.Factory, | ||
private val extrasProducer: () -> CreationExtras = { CreationExtras.Empty } | ||
) : Lazy<VM> { | ||
private var cached: VM? = null | ||
|
||
override val value: VM | ||
get() { | ||
val viewModel = cached | ||
return if (viewModel == null) { | ||
val factory = factoryProducer() | ||
val store = storeProducer() | ||
val canonicalName: String = viewModelClass.java.canonicalName | ||
?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels") | ||
ViewModelProvider( | ||
store, | ||
factory, | ||
extrasProducer() | ||
).get("${keyPrefixProvider()} : $canonicalName", viewModelClass.java).also { | ||
cached = it | ||
} | ||
} else { | ||
viewModel | ||
} | ||
} | ||
|
||
override fun isInitialized(): Boolean = cached != null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package ceui.loxia | ||
|
||
import android.view.View | ||
import androidx.fragment.app.Fragment | ||
import androidx.fragment.app.findFragment | ||
import kotlin.reflect.KClass | ||
|
||
inline fun<reified InterfaceT> Fragment.sendAction(action: (receiver: InterfaceT)->Boolean) { | ||
var received = false | ||
var itr: Fragment? = this | ||
while (itr != null) { | ||
val receiver = itr as? InterfaceT | ||
if (receiver != null && action(receiver)) { | ||
received = true | ||
break | ||
} else { | ||
itr = itr.parentFragment | ||
} | ||
} | ||
|
||
if (!received) { | ||
val receiver = this.activity as? InterfaceT | ||
if (receiver != null) { | ||
action(receiver) | ||
} | ||
} | ||
} | ||
|
||
inline fun<reified InterfaceT> View.sendAction(action: (receiver: InterfaceT)->Boolean) { | ||
val fragment = this.findFragment<Fragment>() | ||
fragment.sendAction<InterfaceT>(action) | ||
} | ||
|
||
inline fun <reified ActionReceiverT> Fragment.findActionReceiverOrNull(): ActionReceiverT? { | ||
var itr: Fragment? = this | ||
while (itr != null) { | ||
val receiver = itr as? ActionReceiverT | ||
if (receiver != null) { | ||
return receiver | ||
} else { | ||
itr = itr.parentFragment | ||
} | ||
} | ||
|
||
return activity as? ActionReceiverT | ||
} | ||
|
||
|
||
inline fun<reified ActionReceiverT> View.findActionReceiverOrNull(): ActionReceiverT? { | ||
val fragment = this.findFragmentOrNull<Fragment>() | ||
return fragment?.findActionReceiverOrNull<ActionReceiverT>() | ||
} | ||
|
||
inline fun<reified ActionReceiverT> View.findActionReceiver(): ActionReceiverT { | ||
val fragment = this.findFragment<Fragment>() | ||
return fragment.findActionReceiverOrNull<ActionReceiverT>()!! | ||
} | ||
|
||
inline fun <reified F : Fragment> View.findFragmentOrNull(): F? { | ||
return try { | ||
val targetFragment = findFragment<Fragment>() | ||
if (targetFragment is F) { | ||
targetFragment as F | ||
} else null | ||
} catch (e: Exception) { | ||
null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters