Android - 在 Kotlin 中声明和使用视图

6

我正在尝试在Android中使用Kotlin,并尝试这样声明LinearLayout:

internal var linlay_SuccessfulPayment : LinearLayout = null!!
internal var linlay_failPayment : LinearLayout

linlay_SuccessfulPayment = findViewById(R.id.linlay_SuccessfulPayment) as LinearLayout
linlay_failPayment = findViewById(R.id.linlay_failPayment) as LinearLayout

但是在日志中我得到了这个信息:
Caused by: kotlin.KotlinNullPointerException
                                                                         at com.example.activities.PaymentResult.<init>(Result.kt:14)
                                                                         at java.lang.Class.newInstance(Native Method)
                                                                         at android.app.Instrumentation.newActivity(Instrumentation.java:1096)
                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3122)
                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415) 
                                                                         at android.app.ActivityThread.access$1100(ActivityThread.java:229) 
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821) 
                                                                         at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                         at android.os.Looper.loop(Looper.java:148) 
                                                                         at android.app.ActivityThread.main(ActivityThread.java:7329) 
                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120

请帮我一下。


无关的事情:在编辑队列中,我遇到了一个你在分类中投票的问题。你在那里做出了错误的选择。请认真研究分类的帮助,并避免将不属于该处的项目放入编辑队列中。请理解你的投票会产生后果!我特别指的是 https://stackoverflow.com/review/triage/20898974。这是(几乎)零工作量的家庭作业转储。只有 OP 可以编辑它来改进它,没有其他人可以!如果您对我有进一步的问题或反馈,请随时给我留言。 - GhostCat
7个回答

8

您的问题与可空性有关,这是使用 lateinit 关键字的好地方(文档)

private lateinit var linlay_SuccessfulPayment: LinearLayout
private lateinit var linlay_failPayment: LinearLayout

这样您定义了一个非空变量,但延迟了初始化,您可以在onCreate()中进行初始化。
在访问它之前,您必须对其进行初始化,否则会出现PropertyNotInitialisedException。
第二个选项是使用属性代理进行延迟初始化:https://kotlinlang.org/docs/reference/delegated-properties.html
private var linlay_SuccessfulPayment: LinearLayout by Delegates.lazy { findViewById(R.id.linlay_SuccessfulPayment) as LinearLayout }

这样的话,视图仅在第一次使用时初始化,而且你可以将所有内容放在一个地方。


4
只需在gradle.build中添加kotlin扩展,您就不需要初始化参数:
apply plugin: 'kotlin-android-extensions'

3
使用!!运算符检查其应用的值是否为null,如果是,则抛出KotlinNullPointerException;否则,它将以非空类型返回该值。写下null!!基本上是throw KotlinNullPointerException(...)的简写。
对于Android Views(以及其他在特殊init方法中初始化对象而不是构造函数的情况),您应该使用lateinit关键字:
internal lateinit var linlay_SuccessfulPayment: LinearLayout
internal lateinit var linlay_failPayment: LinearLayout

这样可以让你在Activity中拥有非空属性,即使在构造函数被调用时你并没有初始化它们,而是稍后在onCreate方法中进行初始化。但是,在这种情况下,你需要在第一次使用变量之前负责初始化它们,否则你将在运行时遇到异常。


1

我刚开始学习 Kotlin,正在尝试学习它。我是这样绑定视图的:

var myBtn: Button = findViewById<Button>(R.id.btnMyButton) as Button

or

var btnLogin: Button = findViewById<Button>(R.id.btnLogin)

我很傻,可是用Kotlin你就不需要绑定视图 :-) - msamardzic

1

像下面这样初始化

internal var linlay_SuccessfulPayment : LinearLayout ?= null
internal var linlay_failPayment : LinearLayout ?= null

并像下面这样使用它
linlay_SuccessfulPayment = findViewById<LinearLayout>(R.id.linlay_SuccessfulPayment)
linlay_failPayment = findViewById<LinearLayout>(R.id.linlay_failPayment)

0

你可以在应用的级别 build.gradle 中使用 apply plugin: 'kotlin-android-extensions',以便绑定视图而无需使用繁琐的 findViewById() 代码。
例如:linlay_failPayment.setParams() // 只需提供 view_id 即可进行任何其他操作
更多信息请查看 kotlin-view-binding


0
你可以像下面这样使用:
 var linlay_SuccessfulPayment : LinearLayout? = null
 var linlay_failPayment : LinearLayout? = null


linlay_SuccessfulPayment = findViewById(R.id.linlay_SuccessfulPayment) as LinearLayout
linlay_failPayment = findViewById(R.id.linlay_failPayment) as LinearLayout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接