【问题标题】:How to use abstraction with ViewBinding with base activity?如何将抽象与 ViewBinding 与基本活动一起使用?
【发布时间】:2020-09-01 10:56:29
【问题描述】:

我正在创建一个基类,以便在基类中设置所有子类的绑定

到此为止

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)

但我正在寻找基础活动中的通用方式

【问题讨论】:

标签: android generic-programming abstraction android-viewbinding


【解决方案1】:

你可以在构造函数中声明一个 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)

【讨论】:

  • 你也可以通过惰性委托定义binding。
【解决方案2】:

其他答案也可以解决问题,但我想以一种干净的方式来做。

我的基类

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

}

我的活动:

class MainActivity : BaseVMActivity<AppViewModel, ActivityMainBinding>() {
    override fun getViewBinding() = ActivityMainBinding.inflate(layoutInflater)
   
}

现在我可以直接访问 viewModel 或绑定了:

fun dummy(){
        binding.bvReport.text = viewModel.getReportText()
    }

【讨论】:

  • 好方法。谢谢
  • 你能用 JAVA 做这个吗,提前谢谢
  • 不适用于继承,例如如果你有 MySecondaryActivity : MainActivity()
  • 你必须打开 MainActivity/abstract 和 MainActivity : BaseVMActivity()
  • 你是对的@Kibotu。当我们想要对其他活动类使用不同的布局和继承时,问题就来了。为什么android强迫我使用泄漏继承?或任何其他使用视图绑定的方法?
【解决方案3】:

我认为在子活动中覆盖绑定对象获取器会更干净。所以:

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)

}

【讨论】:

  • 如果你想用不同的布局扩展 MainActivity,我该如何实现?视图绑定做不到。不喜欢使用视图绑定,我猜它
猜你喜欢
  • 2020-10-06
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 2020-12-30
  • 1970-01-01
  • 2021-08-21
  • 2020-02-13
相关资源
最近更新 更多