首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Anko访问活动的视图

使用Anko访问活动的视图
EN

Stack Overflow用户
提问于 2016-12-07 14:42:55
回答 3查看 3.8K关注 0票数 6

我知道我可以使用Anko的id属性来识别视图:

代码语言:javascript
复制
class MainActivityUI : AnkoComponent<MainActivity> {

    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        frameLayout {
            textView {
                id = R.id.text
            }
        }
    }

}

然后使用Activity函数(或者使用Kotlin扩展)在find()中获得它:

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {

    private val textView by lazy {
        find<TextView>(R.id.text)
    }

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

        textView.text = "Hello World"
    }

}

但是我觉得我错过了什么;自述文件提到find函数或Kotlin扩展的唯一地方是在题为支持现有代码的部分

你不必用Anko重写你所有的UI。您可以使用Java编写旧类。此外,如果您仍然希望(或必须)编写一个Kotlin活动类并出于某种原因膨胀XML布局,您可以使用View属性,这将使事情变得更容易: //与findViewById()相同,更简单地使用val = find(R.id.name) name.hint =“输入您的名称”name.onClick { /*do name.hint*/} 通过使用Kotlin Android扩展,您可以使代码更加紧凑。

这使得find函数看起来只用于支持“旧”XML代码。

所以我的问题是:使用idfind函数是使用Anko从Activity访问View的正确方法吗?有没有更多的“安科”来处理这件事?还是我忽略了Anko的其他一些好处,使得从View访问Activity变得无关紧要?

还有第二个相关的问题:如果这是从View访问Activity的正确方式,那么是否有一种方法可以从AnkoComponent中创建id资源(即"@+id/")?而不是在id文件中创建每个ids.xml

EN

回答 3

Stack Overflow用户

发布于 2016-12-07 15:47:26

那么,为什么仍然使用XML id来定位视图呢?因为我们已经使用了Anko而不是XML。

在我看来,我们可以将视图元素存储在AnkoComponent中而不是find view的id方法中。

代码语言:javascript
复制
class MainActivityUI : AnkoComponent<MainActivity> {

    lateinit var txtView: TextView

    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        frameLayout {
            txtView = textView {
                id = R.id.text // the id here is useless, we can delete this line.
            }
        }
    }

}

class MainActivity : AppCompatActivity() {

    lateinit var mainUI : MainActivityUI

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

        mainUI = MainActivityUI()
        mainUI.setContentView(this)

        mainUI.txtView.text = "Hello World"
    }

}
票数 9
EN

Stack Overflow用户

发布于 2016-12-07 16:57:56

我相信,因为您可以将行为添加到Anko文件中,所以您根本不必在活动中实例化视图。

这真的很酷,因为您可以更多地分离视图层。所有在视图中运行的代码都可以插入到Anko文件中。所以,您所要做的就是从Anko调用您的活动的方法,而不是实例化任何视图。

但如果你需要实例化任何视图..。您可以在活动中使用Kotlin Android扩展。

例:

活动中的代码:

代码语言:javascript
复制
seekBar.setOnSeekBarChangeListener(object: OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
        // Something
    }
    override fun onStartTrackingTouch(seekBar: SeekBar?) {
        // Just an empty method
    }
    override fun onStopTrackingTouch(seekBar: SeekBar) {
        // Another empty method
    }
})

Anko的代码:

代码语言:javascript
复制
seekBar {
    onSeekBarChangeListener {
        onProgressChanged { seekBar, progress, fromUser ->
            // Something
        }
    }
}

现在代码在AnkoComponent中。不需要实例化视图。

结论:

如果您将所有的视图逻辑都放在AnkoComponents中,而不是在您的活动中,这是一种更“Anko”的编程方式。

编辑:

作为代码示例,您不必实例化视图:

在你的安科:

代码语言:javascript
复制
var networkFeedback : TextView = null

    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
            frameLayout {
                textView {
                    id = R.id.text2
                    networkFeedback = this
                    onClick {
                        ui.owner.doSomething(2, this)
                    }
                }
            }
        }

fun networkFeedback(text: String){
       networkFeedback.text = text
}

在你的活动中:

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {

    overriding fun onCreate{
            [...]
            val mainUi = AnkoUi()
            // some dynamic task...
            mainUi.networkFeedback("lalala")
     }

    fun doSomething(number: Int, callback: TextView){
            //Some network or database task goes here!

            //And then, if the operation was successful

            callback.text = "Something has changed..."
        }

这是一种完全不同的方法。我不太确定我是否喜欢,但这是一个完全不同的讨论.

票数 1
EN

Stack Overflow用户

发布于 2018-07-05 18:21:57

概括一下这个问题:如何使封装的AnkoComponent从DSL中使用,并在创建后以编程方式设置其数据?

下面是我如何使用View.tag实现的:

代码语言:javascript
复制
class MyComponent: AnkoComponent<Context> {
    lateinit var innerds: TextView
    override fun createView(ui: AnkoContext<Context>): View {
        val field = with(ui) {
            linearLayout {
                innerds = complexView("hi")
            }
        }
        field.setTag(this) // store the component in the View
        return field
    }

    fun setData(o:SomeObject) { innerds.setStuff(o.getStuff()) }
}

inline fun ViewManager.myComponent(theme: Int = 0) = myComponent(theme) {}
inline fun ViewManager.myComponent(theme: Int = 0, init: MyComponent.() -> Unit) = 
    ankoView({ MyComponent(it) }, theme, init)

// And then you can use it anywhere the Anko DSL is used.
class SomeUser : AnkoComponent<Context>
{
    lateinit var instance:View 
    override fun createView(ui: AnkoContext<Context>): View {
        linearLayout {
            instance = myComponent {}
        }
    }
    fun onDataChange(o:SomeObject) {
        (instance.Tag as MyComponent).setData(o)
    }
}

}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41020345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档