點選檢視程式碼
import android.content.Context
import android.view.LayoutInflater
import androidx.activity.ComponentActivity
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import java.lang.reflect.ParameterizedType
/**
*
* @Description:
* @Author: loongwind
* @CreateDate:2020/8/13 6:07 AM
*
*/
fun getViewModelType(clazz: Class<*>): Class<out ViewModel>? {
val superclass = clazz.genericSuperclass
if (superclass is ParameterizedType) {
//返回表示此型別實際型別引數的 Type 物件的陣列
val actualTypeArguments = superclass.actualTypeArguments
//返回第一個符合條件的 Type 物件
return actualTypeArguments.firstOrNull {
it is Class<*> && ViewModel::class.java.isAssignableFrom(it)
} as? Class<out ViewModel>
}
return null
}
/**
* 根據泛型 BINDING 建立 ViewDataBinding 例項
*/
inline fun <reified BINDING> createDataBinding(context: Context): BINDING {
return getBindingType(BINDING::class.java) // 獲取 ViewDataBinding 泛型實際型別
?.getMethod("inflate", LayoutInflater::class.java) // 反射獲取 inflate 方法
?.invoke(null, LayoutInflater.from(context)) as BINDING // 透過反射呼叫 inflate 方法
}
/**
* 查詢某個類找到帶有指定泛型的具體類
*/
fun getGenericSuperclass(clazz: Class<*>, typClass: Class<*>): Class<*>? {
val superclass = clazz.genericSuperclass
if (superclass is ParameterizedType) {
val actualTypeArguments = superclass.actualTypeArguments
val d = actualTypeArguments.firstOrNull {
it is Class<*> && typClass.isAssignableFrom(it)
}
if (d != null) {
return clazz
}
}
return getGenericSuperclass(clazz.superclass, typClass);
}
fun getBindingType(clazz: Class<*>): Class<*>? {
// val superclass = clazz.genericSuperclass
val superclass = getGenericSuperclass(clazz, ViewDataBinding::class.java)?.genericSuperclass
if (superclass is ParameterizedType) {
//返回表示此型別實際型別引數的 Type 物件的陣列
val actualTypeArguments = superclass.actualTypeArguments
return actualTypeArguments.firstOrNull {
// 判斷是 Class 型別 且是 ViewDataBinding 的子類
it is Class<*> && ViewDataBinding::class.java.isAssignableFrom(it)
} as? Class<*>
}
return null
}
/**
* 簡化ViewModelProvider 使用
*/
inline fun <reified T : ViewModel> ComponentActivity.viewModelProvider(vararg parameters: Any?): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
val factory = CommonViewModeFactory(T::class.java, *parameters)
ViewModelProvider(this, factory)[T::class.java]
}
}
/**
* 簡化ViewModelProvider 使用
*/
inline fun <reified T : ViewModel> Fragment.viewModelProvider(vararg parameters: Any?): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
val factory = CommonViewModeFactory(T::class.java, *parameters)
ViewModelProvider(this, factory)[T::class.java]
}
}
//
//@OptIn(KoinInternalApi::class)
//fun ComponentActivity.injectViewModel() : ViewModel?{
// return getViewModel(javaClass, getKoinScope(), this, viewModelStore )
//}
//
//@OptIn(KoinInternalApi::class)
//fun Fragment.injectViewModel() : ViewModel?{
// return getViewModel(javaClass, getKoinScope(), this, viewModelStore )
//}
//
///**
// * @param javaClass Class型別
// * @param scope koin生命週期範圍
// * @param owner ViewModelStoreOwner 型別,ViewModel 繫結什麼週期物件,Activity、Fragment 都實現了該介面
// * @param viewModelStore 儲存 ViewModel 的物件
// */
//@OptIn(KoinInternalApi::class)
//fun getViewModel(javaClass : Class<*>,
// scope: Scope,
// owner: ViewModelStoreOwner,
// viewModelStore: ViewModelStore) : ViewModel?{
// // 獲取當前 Activity 上 ViewModel 泛型的實際型別
// val viewModel = getViewModelType(javaClass)?.let {
// // 獲取 ViewModelFactory
// val viewModelFactory = getViewModelFactory(owner, it.kotlin, null, null, null, scope)
// //獲取注入的 ViewModel
// ViewModelLazy(it.kotlin, { viewModelStore }, { viewModelFactory} ).value
// }
// return viewModel
//}
//
//