#android #kotlin #android-viewbinding
#Android #kotlin #android-привязка к просмотру
Вопрос:
Есть ли какой-либо способ создать абстрактный класс или интерфейс для привязки к просмотру. Может быть, я покажу простой пример того, что я именно имею в виду.
Допустим, у меня есть два фрагмента. Оба имеют TextView
имена universalTextView
. В классах фрагментов у меня есть значение someText = "Text"
. Я хочу установить это значение universalTextView
равным. Теперь в обоих фрагментах у меня один и тот же код, поэтому я создал абстрактный класс, чтобы уменьшить шаблонный код, который содержит someText
и задает текст universalTextView
. Это выглядит так:
abstract class AbstractFragment(
@LayoutRes layout: Int
) : Fragment(layout)
{
protected abstract val binding: ViewBinding
protected val someText = "Text"
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
binding.root.findViewById<TextView>(R.id.universalTextView).text = someText
}
}
Но при таком подходе я теряю самое большое преимущество привязки к просмотру, и я должен использовать findViewById
. Есть ли какой-нибудь способ создать абстрактный класс для привязки к просмотру, что-то вроде этого:
abstract class AbstractViewBinding : ViewBinding
{
abstract val universalTextView : TextView
}
Таким образом AbstractFragment
, я могу использовать protected abstract val binding: AbstractViewBinding
и изменять текст без использования findViewById
. Но теперь я каким-то образом должен сообщить приложению, что привязка к просмотру, используемая в каждом расширяемом фрагменте, AbstractFragment
будет иметь universalTextView
. Возможно ли это вообще?
Комментарии:
1. @MartinMarconcini Этот TextView — всего лишь простейший пример того, чего я хочу достичь, чтобы каждый мог легко это понять. Если бы были только эти 2 TextViews, в которых значение статически установлено
Text
, я бы никогда не задал этот вопрос: D2. Ах, хорошо 🙂 Я немного волновался. (Вы должны простить меня, иногда вопросы, которые я читаю , касаются этого).
3. В любом случае, я не уверен, что вы можете сделать это таким образом. Вам понадобится «слой», на котором вы переходите от общего «T.setThisText» к «binding1.setThisText» и «binding2.setThisText», и на этом этапе вы просто усложняете, но, конечно, есть веские причины, по которым вы хотели бы абстрагировать некоторые из этих вещейс аналогичными макетами,.
4. Я просто не думаю, что вы можете сделать это с помощью привязки к просмотру, поскольку он разработан так, чтобы быть «типобезопасным» и тому подобное, так что … не имея в виду «общие» вещи.
5. Хорошо, большое вам спасибо. Я думал, что это может быть невозможно сделать так, как я хочу это сделать. Это также не то, что я должен делать, и сделать это даже с помощью a
findViewById
не очень плохо, но мне было просто любопытно, есть ли какой-либо шаблон привязки к абстракции
Ответ №1:
Я не думаю, что это напрямую возможно, в привязке представления нет какого-либо механизма наследования. Вместо этого у вас может быть такая структура:
abstract class AbstractFragment : Fragment {
abstract val universalTextView: TextView
protected val someText = "Text"
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
universalTextView.text = someText
}
}
class Fragment1 : AbstractFragment {
lateinit var binding: Fragment1Binding
override val universalTextView
get() = binding.utv
}
но я понимаю, что это не совсем то, что вы хотели.
Комментарии:
1. Спасибо, это может помочь, но также может создать много шаблонного кода в более сложных примерах. Потому что в каждом фрагменте я должен переопределять одни и те же поля одинаково
2. Да, когда это возможно, избегайте «базовых фрагментов», вместо этого предпочитайте составлять нужные вам поведения в вводимые компоненты, которые вы затем можете вызывать из своих фрагментов (или вызывали автоматически наблюдателями жизненного цикла)