使用Anko访问活动的视图

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

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

然后使用find()函数(或使用Kotlin Android扩展)在Activity获取它:

 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" } } 

但我觉得我失去了一些东西; README中唯一提到find函数或Kotlin Android扩展的地方在标题为支持现有代码的部分:

您不必使用Anko重写所有的用户界面。 你可以保留用Java编写的旧类。 而且,如果您仍然希望(或必须)编写Kotlin活动类并由于某种原因膨胀XML布局,则可以使用“视图”属性,这将使事情变得更加简单:

 // Same as findViewById(), simpler to use val name = find<TextView>(R.id.name) name.hint = "Enter your name" name.onClick { /*do something*/ } 

通过使用Kotlin Android扩展,您可以使代码更加紧凑。

这使得它看起来像find功能只是为了支持“旧”的XML代码。

所以我的问题是这个。 正在使用一个idfind函数一起使用Anko访问Activity View的正确方法? 有更多的“Anko”方式来处理这个? 或者我错过了Anko的一些其他好处,使得从Activity访问View不相关?


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

那么,为什么仍然使用XML id来定位View呢? 因为我们已经使用了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" } } 

我相信,因为您可以将行为添加到您的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”的编程方式。

编辑:

作为一个代码的例子,你不必实例化一个视图:

在你的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..." } 

这是一个非常不同的方法。 我不太确定,如果我喜欢或不喜欢,但这是一个完全不同的讨论…

不要使用ID来识别与Anko DSL的意见! 这是没有必要的,因为Anko是为了摆脱XML布局而设计的。 而是使用这种模式:

 class ActivityMain : AppCompatActivity() { var mTextView: TextView // put it here to be accessible everywhere override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ActivityMainUI().setContentView(this) } fun yourClassMethod() { // So this is am example how to get the textView // defined in your Anko DSL class (not by id!): mTextView.text = "bla-bla-bla" } } class ActivityMainUI : AnkoComponent<ActivityMain> { override fun createView(ui: AnkoContext<ActivityMain>) = with(ui) { // your fancy interface with Anko DSL: verticalLayout { owner.mTextView = textView } } } 

请注意UI类的定义:

 class ActivityMainUI : AnkoComponent<ActivityMain> { 

如果你把活动类的名字放在方括号中,那么所有的公共变​​量都可以通过UI类的主体来访问,所以你可以在那里指定它们。
但是你可以很容易地把AppCompatActivity ,并使一些可能被克隆的通用类。 在这种情况下,使用lateinit var mTextView:TextView在UI类的主体中,如Jacob的答案中所述。