Kotlin / anko

Pleasant Android application development
Apache License 2.0
15.89k stars 1.29k forks source link

How to reference other views? #123

Open maomaobug opened 8 years ago

maomaobug commented 8 years ago

I'm using Anko in my Android project, but I don't know how can it reference the child views I created in the DSL when the referenced view is not at the same level where I reference it.

The following code works:

alert {
    customView {
        val input = textInputLayout {
            editText {
                hint = "Name"
                textColor =resources.getColor(R.color.highlight)
            }
        }
        positiveButton("OK") { "${input.editText.text}" }
    }
}.show()

but the following code does not work:

alert {
    customView {
        val vertical = verticalLayout {
            textView {
                text = "Edit device name"
                textColor = resources.getColor(R.color.highlight)
                textSize = 24F
            }
            val input = textInputLayout {
                editText {
                    hint = "Name"
                    textColor = resources.getColor(R.color.highlight)
                }
            }
        }

        positiveButton("OK") { "${vertical.input.editText.text}" }  // Cannot resolve "input"
    }
}.show()
Ribesg commented 8 years ago

It's not an Anko issue, it's a classic matter of variable scope in code blocks. You declare a local variable input in the block of initialization of your verticalLayout. It obviously does not exist out of its scope.

In this very specific example, you don't actually use the reference to the verticalLayout, but you use a reference to the text input inside it. So just get that reference, declaring the variable in a scope high enough for you to use it.

alert {
    var deviceNameInput: EditText? = null

    customView {
        verticalLayout {
            textView {
                text = "Edit device name"
                textColor = resources.getColor(R.color.highlight)
                textSize = 24F
            }
            textInputLayout {
                deviceNameInput = editText {
                    hint = "Name"
                    textColor = resources.getColor(R.color.highlight)
                }
            }
        }

        positiveButton("OK") { "${deviceNameInput!!.text}" }
    }
}.show()
gregschlom commented 8 years ago

Note that using lateinit var deviceNameInput: EditText might be more convenient

Ribesg commented 8 years ago

More convenient, maybe. But it's a bad idea to keep a reference to a view part of an alert outside of the alert.