2
votes

If we are building a custom View, for example, something like this:

class FrameLayoutNormal: FrameLayout{
constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {

    textView{
         lparams(...)
    }
}

we can't define lparams, because the compiler doesn't know who the parent is. If we wrap the textView inside a FrameLayout it works, and you scan specify a layout parameter. But in a custom view, the parent is itself. So how can we make the children be aware of that so we can use the extension?

Is there any way to get it working, besides extending from: _FrameLayout ?`

1
Why not to extend _FrameLayout? - Dima Rostopira

1 Answers

0
votes

An old question, but since it is common ... Applying the answer from https://github.com/Kotlin/anko/issues/267

I think you might want something like this:

class FrameLayoutNormal: AnkoComponent<Context> {
    override fun createView(ui: AnkoContext<Context>): View {
        return with(ui) {
            frameLayout {
                textView("Hello") {
                }.lparams()
            }
        }
    }
}

inline fun ViewManager.frameLayoutNormal(theme: Int = 0) = frameLayoutNormal(theme) {}
inline fun ViewManager.frameLayoutNormal(theme: Int = 0, init: View.(frameLayoutNormal: FrameLayoutNormal) -> Unit): View {
    val fln = FrameLayoutNormal()
    return ankoView({ fln.createView(AnkoContext.create(it))}, theme, {init(fln)})
}

This allows the component to be used in the ANKO DSL. One downside to this approach is that the custom component is a View, not a ViewGroup, and thus can not have additional children added outside of its definition. It is challenging/laborious to make a custom component which is a ViewGroup that can be used in ANKO DSL (if I understand correctly).