泛型viewmodle

点击查看代码
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
//}
//
//

posted @ 2024-06-29 08:03  烟花易冷心易碎  阅读(2)  评论(0编辑  收藏  举报