Привязка к абстрактному классу или интерфейсу

#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 , я бы никогда не задал этот вопрос: D

2. Ах, хорошо 🙂 Я немного волновался. (Вы должны простить меня, иногда вопросы, которые я читаю , касаются этого).

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. Да, когда это возможно, избегайте «базовых фрагментов», вместо этого предпочитайте составлять нужные вам поведения в вводимые компоненты, которые вы затем можете вызывать из своих фрагментов (или вызывали автоматически наблюдателями жизненного цикла)