Android Studio设置setOnClickListener后应用崩溃问题求助
AlertDialog内按钮点击触发NullPointerException的解决方案
问题根源
你直接在Activity的onCreate方法里调用findViewById获取AlertDialog布局里的按钮,这些按钮属于弹窗专属布局url_dialog.xml,不是主页面布局activity_main.xml的元素。在弹窗还没加载的时候就去查找这些控件,必然返回null,设置点击事件时自然触发空指针异常。
修复后的完整代码
XML布局(无需修改)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/url" android:hint="Enter URL" android:inputType="textPersonName" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/downloadbtn" android:text="Download"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/pastebtn" android:text="Paste"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/cancelbtn" android:text="Cancel"/> </LinearLayout> </LinearLayout>
Kotlin代码(核心修改点已标注)
package com.example.mymusicapp import android.annotation.SuppressLint import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.LayoutInflater import android.widget.Button import androidx.appcompat.app.AlertDialog class MainActivity : AppCompatActivity() { @SuppressLint("MissingInflatedId") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val songbtn = findViewById<Button>(R.id.btnsong) songbtn.setOnClickListener{ // 加载弹窗布局 val mDialogView = LayoutInflater.from(this).inflate(R.layout.url_dialog, null) val mBuilder = AlertDialog.Builder(this) .setView(mDialogView) .setTitle("Download MP3") val mAlertDialog = mBuilder.show() // 关键:通过弹窗的根视图mDialogView查找内部按钮 val downloadbtn = mDialogView.findViewById<Button>(R.id.downloadbtn) val pastebtn = mDialogView.findViewById<Button>(R.id.pastebtn) val cancelbtn = mDialogView.findViewById<Button>(R.id.cancelbtn) // 设置按钮点击事件 downloadbtn.setOnClickListener { // 这里可以添加下载逻辑 mAlertDialog.dismiss() } pastebtn.setOnClickListener { // 这里添加粘贴URL的逻辑 } cancelbtn.setOnClickListener { mAlertDialog.dismiss() } } } }
关键修改说明
- 移除了
onCreate中直接对弹窗按钮的findViewById调用 - 在弹窗布局加载并显示后,通过弹窗的根视图
mDialogView来获取内部控件 - 确保只有弹窗布局加载完成后,才去查找并设置按钮的点击事件
内容的提问来源于stack exchange,提问作者PixelAim
相关产品推荐
相关产品推荐

