Подтвердить что ты не робот

Как использовать 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, но все равно не повезло.

4b9b3361

Ответ 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
}