有人为FragmentActivity
和ViewModel
编写了两个扩展函数(代码A2)以实例化Fragment
,效果很好,您可以看到代码A1和代码A3。
我希望为FragmentActivity
和AndroidViewModel
编写两个扩展函数(代码B2)以实例化class HomeViewModel_A(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {
}
,您可以看到代码B1和代码B3,该怎么办?谢谢!
代码A1
inline fun <reified T : ViewModel> Fragment.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
inline fun <reified T : ViewModel> FragmentActivity.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
代码A2
class FragmentHome : Fragment() {
private val mHomeViewModel_A by lazy {
getViewModel {
HomeViewModel_A(provideRepository(mContext))
}
}
}
代码A3
class HomeViewModel_B(application: Application,private val mDBVoiceRepository: DBVoiceRepository) : AndroidViewModel(application) {
}
代码B1
?
代码B2
class FragmentHome : Fragment() {
private val mHomeViewModel_B by lazy {
?
}
}
代码B3
Container(
child: SingleChildScrollView(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hello,',
style: Theme.of(context)
.textTheme
.headline4
.apply(color: Colors.grey),
),
Text(
"Mr. Udeinya",
style: Theme.of(context)
.textTheme
.headline4
.apply(color: Colors.deepOrange, fontWeightDelta: 2),
),
],
),
Container(
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.deepOrange,
border: Border.all(
width: 3,
color: Colors.white,
)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Wallet Balance :',
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(
height: 10.0,
),
Container(
width: double.infinity,
)
],
),
),
],
),
),
)
答案 0 :(得分:4)
Ktx Fragments库已经具有一个功能,用于简洁地创建一个懒惰的委托来检索视图模型:Fragment.viewModels()
和FragmentActivity.viewModels()
。
这些适用于具有默认构造函数(分别为空或Application参数)的ViewModel和AndroidViewModels,或者您可以使用尾随lambda返回视图模型工厂。您可以这样使用它:
class FragmentHome : Fragment() {
private val mHomeViewModel_B: MyViewModel by viewModels()
}
或
class FragmentHome : Fragment() {
private val mHomeViewModel_B: MyViewModel by viewModels { getMyViewModelFactory() }
}
要获得与 A2 中相同的功能,可以包装此函数以为您建立工厂:
@Suppress("UNCHECKED_CAST")
inline fun <reified VM : ViewModel> Fragment.viewModelFactory(crossinline creator: () -> VM): Lazy<VM> {
return viewModels {
object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return creator() as T
}
}
}
}
答案 1 :(得分:0)
by viewModels(...)
是fragment-ktx库的一部分,它是创建lazy
委托以获得ViewModels
的便捷代表。
// creates lazy delegate for obtaining zero-argument MyViewModel
private val viewModel : MyViewModel by viewModels()
// it's functionally equal to:
private val viewModel by lazy {
ViewModelProvider(this).get(MyViewModel::class.java)
}
// with factory:
private val viewModel : MyViewModel by viewModels { BaseViewModelFactory { } }
// is equal to:
private val viewModel by lazy {
ViewModelProvider(this, BaseViewModelFactory { }).get(MyViewModel::class.java)
}
class BaseViewModelFactory(val creator: () -> ViewModel) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return creator() as T
}
}