Как использовать абстракцию с ViewBinding с базовой активностью?

Я создавал базовый класс, чтобы все привязки для дочерних элементов были установлены в базовом

Я сделал до этого

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)

но я ищу обобщенный способ в базовой деятельности


person Mirza Ahmed Baig    schedule 01.09.2020    source источник
comment
Отвечает ли это на ваш вопрос? Как использовать ViewBinding с абстрактным базовым классом   -  person Chetan Gupta    schedule 06.12.2020


Ответы (2)


Вы можете объявить лямбда-свойство в конструкторе для создания объекта привязки.

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)
person Sinner of the System    schedule 20.10.2020
comment
Вы также можете определить binding с помощью ленивого делегата. - person YaMiN; 01.07.2021
comment
Верно! Спасибо. - person Sinner of the System; 08.07.2021

Другой ответ также решит проблему, но я хотел бы сделать это чисто.

Мой базовый класс

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()
    }
person Mirza Ahmed Baig    schedule 21.10.2020
comment
Хороший и легкий способ. Спасибо - person Bhavnik; 13.12.2020
comment
не могли бы вы сделать это на JAVA, заранее спасибо - person Ali Tamoor; 23.06.2021
comment
не работает с наследованием, например если у вас есть MySecondaryActivity: MainActivity () - person Kibotu; 08.07.2021
comment
вы должны сделать MainActivity открытым / абстрактным и MainActivity ‹VM: AppViewModel, B: ViewBinding›: BaseVMActivity ‹AppViewModel, ActivityMainBinding› () - person Mirza Ahmed Baig; 09.07.2021