如何使用带有 base activity 的 ViewBinding 进行抽象?
How to use abstraction with ViewBinding with base activity?
我正在制作一个 base class 以便子项的所有绑定都将在 base
中设置
我已经做到了这一点
abstract class BaseActivity2<B : ViewBinding?, T : BaseViewModel?> : AppCompatActivity() {
private var viewBinding: B? = null
private var baseViewModel: T? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
但我无法找到在 oncreat() 中绑定视图的方法
通常我们在视图绑定中将布局绑定为
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
但我正在寻找 base activity
中的通用方法
您可以在构造函数中声明一个 lambda 属性 来创建绑定对象
abstract class BaseActivity<B : ViewBinding>(val bindingFactory: (LayoutInflater) -> B) : AppCompatActivity() {
private lateinit var binding: B
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = bindingFactory(layoutInflater)
setContentView(binding.root)
}
}
你也可以定义binding
为懒惰属性
private val binding: B by lazy { bindingFactory(layoutInflater) }
那么你不需要在你的活动中覆盖任何东西
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate)
其他答案也能解决问题,但我想以一种干净的方式来做。
我的基地Class
abstract class BaseVMActivity<VM : ViewModel, B : ViewBinding> : BaseActivity() {
lateinit var viewModel: VM
lateinit var binding: B
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this, factory).get(getViewModelClass())
binding = getViewBinding()
setContentView(binding.root)
}
private fun getViewModelClass(): Class<VM> {
val type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
return type as Class<VM>
}
abstract fun getViewBinding(): B
}
我的activity:
class MainActivity : BaseVMActivity<AppViewModel, ActivityMainBinding>() {
override fun getViewBinding() = ActivityMainBinding.inflate(layoutInflater)
}
现在我可以直接访问 viewModel 或绑定:
fun dummy(){
binding.bvReport.text = viewModel.getReportText()
}
我认为覆盖子 activity 内部的绑定对象 getter 更清晰。所以:
abstract class VBActivity<VB : ViewBinding> : AppCompatActivity() {
protected abstract val binding: VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
}
假设 MainActivity 类似于:
class MainActivity : VBActivity<ActivityMainBinding>() {
override val binding get() = ActivityMainBinding.inflate(layoutInflater)
}
我正在制作一个 base class 以便子项的所有绑定都将在 base
中设置我已经做到了这一点
abstract class BaseActivity2<B : ViewBinding?, T : BaseViewModel?> : AppCompatActivity() {
private var viewBinding: B? = null
private var baseViewModel: T? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
但我无法找到在 oncreat() 中绑定视图的方法 通常我们在视图绑定中将布局绑定为
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
但我正在寻找 base activity
中的通用方法您可以在构造函数中声明一个 lambda 属性 来创建绑定对象
abstract class BaseActivity<B : ViewBinding>(val bindingFactory: (LayoutInflater) -> B) : AppCompatActivity() {
private lateinit var binding: B
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = bindingFactory(layoutInflater)
setContentView(binding.root)
}
}
你也可以定义binding
为懒惰属性
private val binding: B by lazy { bindingFactory(layoutInflater) }
那么你不需要在你的活动中覆盖任何东西
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate)
其他答案也能解决问题,但我想以一种干净的方式来做。
我的基地Class
abstract class BaseVMActivity<VM : ViewModel, B : ViewBinding> : BaseActivity() {
lateinit var viewModel: VM
lateinit var binding: B
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this, factory).get(getViewModelClass())
binding = getViewBinding()
setContentView(binding.root)
}
private fun getViewModelClass(): Class<VM> {
val type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
return type as Class<VM>
}
abstract fun getViewBinding(): B
}
我的activity:
class MainActivity : BaseVMActivity<AppViewModel, ActivityMainBinding>() {
override fun getViewBinding() = ActivityMainBinding.inflate(layoutInflater)
}
现在我可以直接访问 viewModel 或绑定:
fun dummy(){
binding.bvReport.text = viewModel.getReportText()
}
我认为覆盖子 activity 内部的绑定对象 getter 更清晰。所以:
abstract class VBActivity<VB : ViewBinding> : AppCompatActivity() {
protected abstract val binding: VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
}
假设 MainActivity 类似于:
class MainActivity : VBActivity<ActivityMainBinding>() {
override val binding get() = ActivityMainBinding.inflate(layoutInflater)
}