在belwo示例中,我该如何对TextView进行惰性初始化。 我试图通过lateinit进行初始化,但仍能正常工作,但无法通过惰性Lampda函数完成
活动
npm
答案 0 :(得分:1)
您应该使用var
val
val mTextViewResult : TextView by lazy { findViewById(R.id.tvResult) }
还有,如果应用了kotlin android extensions插件,您也不必调用findViewById()
。
在应用程序级别build.gradle
中添加kotlin android扩展插件
apply plugin: "com.android.application"
apply plugin: "kotlin-android"
apply plugin: "kotlin-kapt"
apply plugin: "kotlin-android-extensions" // this plugin
...
现在,您可以通过导入布局参考来使用tvResult
。
import kotlinx.android.synthetic.main.<layout>.*
class MainActivity : AppCompatActivity{
...
}
答案 1 :(得分:0)
我建议您使用DataBinding library来简化初始化/使用布局项目。
执行以下操作:
class YourClassActivity() {
private var myTextView : TextView? = null // At first, myTextView is null. Do not use it !
private var viewModel = YourViewModel()
override fun onCreate(...) {
val binding = DataBindingUtil.setContentView<ActivityYourClassBinding>(this, R.layout.activity_your_class) // DataBinding will set your view
binding.viewModel = yourViewModel
// Init layout variables
myTextView = binding.myTextView // If your TextView id is "my_text_view"
/*
** Now you can use 'myTextView' in any of your function (not just onCreate).
** Just do not forget to put the nullable '?' mark after its name.
*/
myTextView?.text = "Hello World"
myTextView?.setOnClickListener { clear() }
}
private fun clear() {
myTextView?.text = "" // You can use your variable anywhere you want !
}
}
答案 2 :(得分:0)
您不能将lazy
与var
一起使用。您可以在onCreate中使用var lateinit mTextViewResult : TextView
和mTextViewResult = findViewById(...),也可以使用synthetics通过XML中定义的ID访问TextView。
答案 3 :(得分:0)
public fun <V : View> Activity.bindView(id: Int)
: ReadOnlyProperty<Activity, V> = required(id, viewFinder)
private val Activity.viewFinder: Finder<Activity>
get() = { findViewById(it) }
private fun viewNotFound(id: Int, desc: KProperty<*>): Nothing =
throw IllegalStateException("View ID $id for '${desc.name}' not found.")
@Suppress("UNCHECKED_CAST")
private fun <T, V : View> required(id: Int, finder: Finder<T>) =
Lazy { t: T, desc -> t.finder(id) as V? ?: viewNotFound(id, desc) }
typealias Finder<T> = T.(Int) -> View?
// Like Kotlin's lazy delegate but the initializer gets the target and metadata passed to it
private class Lazy<T, V>(private val initializer: (T, KProperty<*>) -> V) : ReadOnlyProperty<T, V>, LifecycleObserver {
private object EMPTY
private var value: Any? = EMPTY
private var attachedToLifecycleOwner = false
override fun getValue(thisRef: T, property: KProperty<*>): V {
checkAddToLifecycleOwner(thisRef)
if (value == EMPTY) {
value = initializer(thisRef, property)
}
@Suppress("UNCHECKED_CAST")
return value as V
}
private fun checkAddToLifecycleOwner(thisRef: T) {
if (!attachedToLifecycleOwner && thisRef is LifecycleOwner) {
thisRef.lifecycle.addObserver(this)
attachedToLifecycleOwner = true
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun destroy() {
value = EMPTY
}
}
并像这样使用它:
class MainActivity : AppCompatActivity() {
private val mTv: TextView by bindView(R.id.tv)
}