我知道我可以使用Anko的id属性来识别视图:
class MainActivityUI : AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
frameLayout {
textView {
id = R.id.text
}
}
}
}然后使用Activity函数(或者使用Kotlin扩展)在find()中获得它:
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代码。
所以我的问题是:使用id和find函数是使用Anko从Activity访问View的正确方法吗?有没有更多的“安科”来处理这件事?还是我忽略了Anko的其他一些好处,使得从View访问Activity变得无关紧要?
还有第二个相关的问题:如果这是从View访问Activity的正确方式,那么是否有一种方法可以从AnkoComponent中创建id资源(即"@+id/")?而不是在id文件中创建每个ids.xml。
发布于 2016-12-07 15:47:26
那么,为什么仍然使用XML id来定位视图呢?因为我们已经使用了Anko而不是XML。
在我看来,我们可以将视图元素存储在AnkoComponent中而不是find view的id方法中。
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"
}
}发布于 2016-12-07 16:57:56
我相信,因为您可以将行为添加到Anko文件中,所以您根本不必在活动中实例化视图。
这真的很酷,因为您可以更多地分离视图层。所有在视图中运行的代码都可以插入到Anko文件中。所以,您所要做的就是从Anko调用您的活动的方法,而不是实例化任何视图。
但如果你需要实例化任何视图..。您可以在活动中使用Kotlin Android扩展。
例:
活动中的代码:
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的代码:
seekBar {
onSeekBarChangeListener {
onProgressChanged { seekBar, progress, fromUser ->
// Something
}
}
}现在代码在AnkoComponent中。不需要实例化视图。
结论:
如果您将所有的视图逻辑都放在AnkoComponents中,而不是在您的活动中,这是一种更“Anko”的编程方式。
编辑:
作为代码示例,您不必实例化视图:
在你的安科:
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
}在你的活动中:
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..."
}这是一种完全不同的方法。我不太确定我是否喜欢,但这是一个完全不同的讨论.
发布于 2018-07-05 18:21:57
概括一下这个问题:如何使封装的AnkoComponent从DSL中使用,并在创建后以编程方式设置其数据?
下面是我如何使用View.tag实现的:
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)
}
}}
https://stackoverflow.com/questions/41020345
复制相似问题