Skip to content
This repository has been archived by the owner on Jul 13, 2020. It is now read-only.

DSL: Unable to refer to views outside of the current scope #17

Closed
DavidYKay opened this issue Apr 10, 2015 · 4 comments
Closed

DSL: Unable to refer to views outside of the current scope #17

DavidYKay opened this issue Apr 10, 2015 · 4 comments

Comments

@DavidYKay
Copy link

Anko team,

Thanks for the great library. :)

I'm having trouble referring to views outside the current scope.

My use case is to call an EditText from a button that lives in a different layout/ViewGroup.

Please look at the below examples to see what I am trying to accomplish. It's possible that there's a way that I'm not seeing.

Example A - Button and EditText as siblings

Works! :)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    verticalLayout {
        val name = editText() {
            id = nameId
        }
        button("Register") {
            onClick {
                toast("Hello, ${name.text}!")
            }
        }
    }
}

Example B - Button and EditText in separate ViewGroups

Won't compile - name is used outside scope

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    relativeLayout {
        verticalLayout {
            val name = editText() {
                id = nameId
            }
        }
        button("Register") {
            onClick {
                toast("Hello, ${name.text}!")
            }
        }
    }
}

Example C - Passing instantiated EditText into DSL

Runs, but name doesn't create an actual instance of editText inside relativeLayout. So there's no editText in the UI.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val name = editText() {

    relativeLayout {
        verticalLayout {
            val name = editText() {
                id = nameId
            }
        }
        button("Register") {
            onClick {
                toast("Hello, ${name.text}!")
            }
        }
    }

}

Example D - findViewById

Crash at runtime - findViewById returns a View, not an EditText

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val name = editText() {

    val nameId = 1
    relativeLayout {
        verticalLayout {
            val name = editText() {
                id = nameId
            }
        }
        button("Register") {
            onClick {
                // fails with: android.view.View! cannot be cast to T
                val name = find<EditText>(nameId)
                // fails with: android.view.View! cannot be cast to android.widget.EditText
                val name: EditText = findViewById(nameId) as EditText
                toast("Hello, ${name.text}!")
            }
        }
    }

}

Many thanks for your time and attention. Let me know how I can help get this resolved.

@DavidYKay
Copy link
Author

Update:

I got this working by using an instance variable, like so:

var nameBox: EditText? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    relativeLayout {
        verticalLayout {
            val name = editText() {
                id = nameId
            }
            nameBox = name
        }
        button("Register") {
            onClick {
                toast("Hello, ${nameBox!!.text}!")
            }
        }
    }
}

@yoavst
Copy link

yoavst commented Apr 13, 2015

better use var nameBox: EditText by Delgates.notNull()

@DavidYKay
Copy link
Author

Excellent. I'm a Kotlin newbie and was unaware of that. Thanks again and sorry for not reading the docs more closely!

@yanex yanex added the question label Apr 14, 2015
@yanex yanex closed this as completed Apr 14, 2015
@yanex
Copy link
Member

yanex commented May 3, 2017

Just in case: Kotlin now has late-initialized variables (https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties) which don't create an extra delegate object.

@yanex yanex added the fixed label May 3, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants