泛型viewmodle

烟花易冷心易碎發表於2024-06-29
點選檢視程式碼
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
//}
//
//

相關文章