Как использовать Anko DSL внутри фрагмента?
Страница Github wiki показывает этот пример, который будет использоваться в экземпляре Activity
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
padding = dip(30)
editText {
hint = "Name"
textSize = 24f
}
editText {
hint = "Password"
textSize = 24f
}
button("Login") {
textSize = 26f
}
}
}
Как сделать то же самое внутри Fragment
?
Я попытался поместить этот блок verticalLayout
в onCreateView
, но метод не может быть разрешен. Я добавил зависимость anko-support-v4
, но все равно не повезло.
Ответы
Ответ 1
После выкапывания anko-support-v4
исходного кода плюс некоторые пробные версии и ошибки, я нашел обходное решение, хотя я не уверен, правильно ли он/рекомендован. Это кажется немного недокументированным.
Образец из моего кода Fragment
:
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return UI {
verticalLayout {
linearLayout {
avatar = imageView().lparams(width = dip(48), height = dip (48))
name = textView().lparams(width = 0, weight = 1f)
}
linearLayout {
// ...
}
}
}.toView()
}
Я возвращаю макет DSL, завернутый в UI { ... }.toView()
в Fragment.onCreateView(...)
Ответ 2
С помощью Anko 0.8 вы также можете использовать AnkoComponent
, если хотите сохранить свой интерфейс в отдельном классе, чтобы его можно было повторно использовать в другом месте.
class FragmentUi<T>: AnkoComponent<T> {
override fun createView(ui: AnkoContext<T>) = with(ui) {
verticalLayout {
// ...
}
}
}
Вы можете вызвать его в своем фрагменте onCreateView()
на
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View
= FragmentUi<Fragment>().createView(AnkoContext.create(ctx, this))
Ответ 3
По сравнению с anko 0.8.1 правильным кодом будет:
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return UI {
verticalLayout {
linearLayout {
// ...
}
linearLayout {
// ...
}
}
}.view
}