Button.setOnLongClickListener失效:单击显示默认Toast长按不显示自定义Toast
问题描述
想要实现按钮单击显示默认Toast、长按显示自定义Toast的功能,但目前程序启动就崩溃,自定义Toast无法触发,默认Toast也无法正常显示。
相关代码
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) btntoste.setOnClickListener { Toast.makeText(this,"this is defult toaste",Toast.LENGTH_SHORT) } btntoste.setOnLongClickListener { Toast(this).apply { duration = Toast.LENGTH_LONG view = layoutInflater.inflate(R.layout.custom_toaste, layconstrain) show() } } } }
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/btntoste" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Toste" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.266" android:backgroundTint="@color/material_dynamic_neutral50" android:textColor="@color/white"/> </androidx.constraintlayout.widget.ConstraintLayout>
自定义Toast布局 custom_toaste.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/layconstrain" android:padding="16dp" android:background="@color/material_dynamic_neutral70"> <ImageView android:id="@+id/imageView" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/ic_baseline_circle_notifications_24" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/txtcucont" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:text="Hay this is custom toaste" android:textSize="15sp" android:textColor="@color/purple_700" app:layout_constraintBottom_toBottomOf="@+id/imageView" app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.583" /> </androidx.constraintlayout.widget.ConstraintLayout>
Logcat错误信息
failed to add asset path /data/app/com.sumita.toaste-wg1Yd4-KC7e1sn36eDPchA==/base.apk 2023-05-10 11:58:44.858 18737-18737 ResourcesManager pid-18737 E failed to add asset path /data/app/com.sumita.toaste-wg1Yd4-KC7e1sn36eDPchA==/base.apk 2023-05-10 11:58:44.861 18737-18737 ResourcesManager pid-18737 E failed to add asset path /data/app/com.sumita.toaste-wg1Yd4-KC7e1sn36eDPchA==/base.apk 2023-05-10 11:58:45.088 2461-2501 ActivityThread com.sumita.toaste E Failed to find provider info for cn.teddymobile.free.anteater.den.provider 2023-05-10 11:58:45.229 2461-2461 AndroidRuntime com.sumita.toaste E FATAL EXCEPTION: main Process: com.sumita.toaste, PID: 2461 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sumita.toaste/com.sumita.toaste.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2994) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3072) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1766) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:6977) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:528) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:910) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at com.sumita.toaste.MainActivity.onCreate(MainActivity.kt:17) at android.app.Activity.performCreate(Activity.java:7227) at android.app.Activity.performCreate(Activity.java:7218) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3072) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1766) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:6977) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:528) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:910)
问题分析与修复方案
核心问题
- 按钮实例为空:直接使用
btntoste但未正确绑定视图,导致空指针异常,程序启动即崩溃,根本无法触发后续的点击/长按事件。 - 默认Toast未调用
show():Toast.makeText()创建实例后未执行show(),所以默认Toast也不会显示。 - 自定义Toast布局加载错误:
inflate(R.layout.custom_toaste, layconstrain)中的layconstrain是自定义布局里的ID,此时尚未加载该布局,传入会导致空指针,且Toast的视图不需要指定父容器,应传null。 - 长按事件未返回布尔值:
setOnLongClickListener要求返回布尔值,用于标记事件是否被消费。
修复步骤
1. 绑定按钮视图
可以选择两种方式:
- 方式一:使用视图绑定(推荐)
在模块的build.gradle中启用视图绑定:
然后在Activity中使用:android { ... buildFeatures { viewBinding true } }val binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // 用binding.btntoste访问按钮 - 方式二:手动findViewById
在setContentView后添加:val btntoste = findViewById<Button>(R.id.btntoste)
2. 修复默认Toast代码
添加show()方法:
Toast.makeText(this,"this is default toast",Toast.LENGTH_SHORT).show()
3. 修复自定义Toast布局加载
将inflate的第二个参数改为null:
view = layoutInflater.inflate(R.layout.custom_toaste, null)
4. 补全长按事件返回值
在长按事件的最后返回true,表示消费该事件:
true
完整修复后的代码
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 手动绑定按钮视图 val btntoste = findViewById<Button>(R.id.btntoste) btntoste.setOnClickListener { // 默认Toast添加show() Toast.makeText(this,"this is default toast",Toast.LENGTH_SHORT).show() } btntoste.setOnLongClickListener { Toast(this).apply { duration = Toast.LENGTH_LONG // 修复布局加载的父容器参数 view = layoutInflater.inflate(R.layout.custom_toaste, null) show() } // 返回true表示消费长按事件 true } } }
内容的提问来源于stack exchange,提问作者Sumita Das
相关产品推荐
相关产品推荐

