如何在视图中使用属性.OnClickListener(kotlin,android)



请使用翻译器进行理解。下面是我写的代码。

val lister = object : View.OnClickListener{
val textView1:TextView = findViewById(R.id.textView1)
val toggleButton1:ToggleButton = findViewById(R.id.toggleButton1)
override fun onClick(v: View?) {
if(toggleButton1.isChecked == true) {
textView1.text = "ON"
}else{
textView1.text = "OFF"
}
}
}

但是这个代码不起作用。错误名称为E/AndroidRuntime:致命异常:main所以我像下面的代码一样修改了它。

val lister1 = object : View.OnClickListener{
override fun onClick(v: View?) {
val toggleButton1:ToggleButton = findViewById(R.id.toggleButton1)
val textView1:TextView = findViewById(R.id.textView1)
if(toggleButton1.isChecked == true) {
textView1.text = "ON"
}else{
textView1.text = "OFF"
}
}
}

当我将toggleButton1和textView1属性移动到onclick函数时,效果很好。但我想知道,当我像第一段代码一样编写它时,为什么它不起作用。如果你能告诉我,我将不胜感激。以下是全部错误。

E/AndroidRuntime:致命异常:main流程:kr.co.yeaeun.viewbasic,PID:11834java.lang.RuntimeException:无法实例化活动ComponentInfo{kr.co.yeaeun.viewbasic/kr.co.yeaeun.viewbasic.MainActivity}:java.lang.NullPointerException:尝试在null对象引用上调用虚拟方法"android.content.pm.ApplicationInfo android.coontent.Context.getApplicationInfo()"在android.app.ActivityThread.performLaunchActivity(ActivityThreads.java:3365)在android.app.ActivityThread.handleLaunchActivity(ActivityThreads.java:3601)在android.app.servertransaction.LaunchActivityItem.exexecute(LaunchActivityItem.java:85)在android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)在android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)在android.app.ActivityThread$H.handleMessage(ActivityThreads.java:2066)在android.os.Handler.dispatchMessage(Handler.java:106)在android.os.Looper.loop(Looper.java:223)在android.app.ActivityThread.main(ActivityThreads.java:7656)位于java.lang.reflect.Method.ioke(本机方法)网址:com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)网址:com.android.internal.os.ZygoteInit.main(ZygoteNit.java:947)由以下原因引起:java.lang.NullPointerException:试图对null对象引用调用虚拟方法"android.content.pm.ApplicationInfo android.coontent.Context.getApplicationInfo()"在android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:173)在android.view.ContextThemeWrapper.getTheme(ContextThemeWraper.java:174)在android.content.Context.georgentStyledAttributes上(Context.java:744)位于androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDeleateImpl.java:839)位于androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDeleateImpl.java:806)位于androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDeleateImpl.java:630)位于androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:223)访问kr.co.yeaeun.viewbasic.MainActivity$lister1$1。(MainActivity.kt:55)访问kr.co.yeaeun.viewbasic.MainActivity.(MainActivity.kt:54)位于java.lang.Class.newInstance(本机方法)在android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)位于androidx.core.app.CoreComponentFactory.instantiateActivity(CoreCompoonentFactory.java:45)在android.app.Instrumentation.newActivity(Instrumentation.java:1253)在android.app.ActivityThread.performLaunchActivity(ActivityThreads.java:3353)在android.app.ActivityThread.handleLaunchActivity(ActivityThreads.java:3601)在android.app.servertransaction.LaunchActivityItem.exexecute(LaunchActivityItem.java:85)在android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)在android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)在android.app.ActivityThread$H.handleMessage(ActivityThreads.java:2066)在android.os.Handler.dispatchMessage(Handler.java:106)在android.os.Looper.loop(Looper.java:223)在android.app.ActivityThread.main(ActivityThreads.java:7656)位于java.lang.reflect.Method.ioke(本机方法)网址:com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)网址:com.android.internal.os.ZygoteInit.main(ZygoteNit.java:947)

完整代码

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView1:TextView = findViewById(R.id.textView1)
//val textView2:TextView = findViewById(R.id.textView2)
val toggleButton1:ToggleButton = findViewById(R.id.toggleButton1)
val toggleButton2:ToggleButton = findViewById(R.id.toggleButton2)
val button1:Button = findViewById(R.id.button1)
val button2:Button = findViewById(R.id.button2)
val button3:Button = findViewById(R.id.button3)
val button4:Button = findViewById(R.id.button4)
button1.setOnClickListener{
if(toggleButton1.isChecked == true){
textView1.text = "ON"
} else{
textView1.text = "OFF"
}
}
button2.setOnClickListener{
toggleButton1.isChecked = true
}
button3.setOnClickListener{
toggleButton1.isChecked = false
}
button4.setOnClickListener {
toggleButton1.toggle()
}
toggleButton1.setOnClickListener(lister1)
toggleButton2.setOnClickListener {
val textView2:TextView = findViewById(R.id.textView2)
if(toggleButton1.isChecked == true) {
textView2.text = "ON"
}else{
textView2.text = "OFF"
}
}
}
val lister1 = object : View.OnClickListener{
override fun onClick(v: View?) {
val toggleButton1:ToggleButton = findViewById(R.id.toggleButton1)
val textView1:TextView = findViewById(R.id.textView1)
if(toggleButton1.isChecked == true) {
textView1.text = "ON"
}else{
textView1.text = "OFF"
}
}
}

}

现在,当我看到完整的代码时,很容易说出问题出在哪里。请参阅这个Java代码示例,它将抛出RuntimeException:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTakePhoto = findViewById(R.id.take_photo);
btnTakePhoto.setOnClickListener(listener);
}

View.OnClickListener listener = new View.OnClickListener() {
Button btnTakePhoto = findViewById(R.id.take_photo);
@Override
public void onClick(View v) {
if (btnTakePhoto.getVisibility() == View.VISIBLE) {
Toast.makeText(MainActivity.this, "dszfa", Toast.LENGTH_SHORT).show();
}
}
};
}

所以我在这里把监听器定义为一个活动字段。然后发生了什么?此字段在调用onCreate()方法之前进行初始化。所以没有地方可以找到按id查看,因为您以前没有设置内容视图!如果将代码Button btnTakePhoto = findViewById(R.id.take_photo);放在onClick方法中,则会有所不同。在创建视图之前,不可能有人按下按钮。

视图。CustomListener不是视图。它是一个Listener类。你需要像next一样使用smth,但这是一种糟糕的方式。侦听器不应将ui视图保存为属性

class CustomView : View {
...
inner class CustomListener : View.OnClickListener{
val toggleButton1:ToggleButton = this@CustomView.findViewById(R.id.toggleButton1)
val textView1:TextView = this@CustomView.findViewById(R.id.textView1)
override fun onClick(v: View?) {
if(toggleButton1.isChecked == true) {
textView1.text = "ON"
}else{
textView1.text = "OFF"
}
}
}
}

如果toggleButton1和textView是侦听视图的子级,则可以使用

val lister1 = object : View.OnClickListener{
override fun onClick(v: View?) {
val toggleButton1:ToggleButton? = view?.findViewById(R.id.toggleButton1)
val textView1:TextView? = view?.findViewById(R.id.textView1)
if(toggleButton1?.isChecked == true) {
textView1?.text = "ON"
}else{
textView1?.text = "OFF"
}
}
}

工作样品

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.view_main)
val button = findViewById<Button>(R.id.button)
(button as View).setOnClickListener(listener)
}
val listener = object : View.OnClickListener {
override fun onClick(view: View?) {
val b = this@MainActivity.findViewById<TextView>(R.id.textView)
println("${b?.text}")
}
}
}

应用此插件

apply plugin: 'kotlin-android-extensions'

设置后点击监听器查看如下

toggleButton1?.setOnCheckedChangeListener{ _, isCheked ->
textView1?.text = if (isChecked) "ON" else "OFF"
}

更新

没有kotlin合成也没有问题

val toggleButton1: ToggleButton? = findViewById(R.id.toggleButton1)
val textView1: TextView? = findViewById(R.id.textView1)
toggleButton1?.setOnCheckedChangeListener { _, isChecked ->  } {
textView1?.text = if (isChecked) "ON" else "OFF"
}

最新更新