Android Kotlin findViewById must not be null
我们已经创建了一个自定义警报对话框,该对话框已在Java项目中使用,方法是将其转换为Kotlin。
java.lang.IllegalStateException:findViewById(R.id.btnYES)不能为null
错误原因使我们难以理解!我们查看了许多帖子,并尝试了一些没有结果的帖子。 Activity结构如下:PageTwoActivity具有自己的XML文件,并带有两个按钮。自定义对话框具有自己的xml文件
这是PageTwoActivity代码。没有两个用于PageTwoActivity的按钮
没有名称冲突
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import android.app.Dialog import android.content.Intent import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.Button import android.widget.EditText import android.widget.Toast class PageTwoActivity : AppCompatActivity() { internal lateinit var btnBACK: Button internal lateinit var btnDIALOG: Button internal lateinit var btnYES: Button internal lateinit var btnNO: Button internal lateinit var etStudentName:EditText var EnteredText: String ="" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_page_two) btnBACK = findViewById(R.id.btnBACK) btnDIALOG = findViewById(R.id.btnDIALOG) btnYES = findViewById(R.id.btnYES) btnNO = findViewById(R.id.btnNO) etStudentName = findViewById(R.id.etStudentName) addListenerOnButtonBACK() addListenerOnButtonDIALOG() Toast.makeText(this@PageTwoActivity,"You are on Page Two", Toast.LENGTH_LONG).show() }// END onCreate |
这是自定义对话框的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | private fun doCustom() { val openDialog = Dialog(this) openDialog.setContentView(R.layout.custom_dialog) //val btnYES = view!!.findViewById<Button>(R.id.btnYES) //val btnNO = openDialog.findViewById(R.id.btnNO) //val etStudentName = openDialog.findViewById(R.id.etStudentName) openDialog.setCancelable(false) btnYES.setOnClickListener(View.OnClickListener { EnteredText = etStudentName.getText().toString().trim({ it <= ' ' }) if (EnteredText.isEmpty()) { Toast.makeText(applicationContext,"Enter Your Name\ \ OR Click DECLINE", Toast.LENGTH_LONG).show() return@OnClickListener } Toast.makeText(applicationContext,"Registered $EnteredText", Toast.LENGTH_SHORT).show() openDialog.dismiss() }) btnNO.setOnClickListener(View.OnClickListener { EnteredText ="" val intent = Intent(this@PageTwoActivity, MainActivity::class.java) startActivity(intent) openDialog.dismiss() }) openDialog.show() } |
自定义对话框的XML文件代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="400dp" android:layout_height="200dp" android:background="@color/color_lightGray"> <TextView android:id="@+id/tvDAT" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="70dp" android:layout_marginTop="30dp" android:text="Enter First and Last Name" android:textColor="@color/color_Black" android:textSize="22sp" android:textStyle="bold" /> <EditText android:id="@+id/etStudentName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginTop="80dp" android:ems="14" android:gravity="center" android:inputType="textPersonName" android:text="" android:textColor="@color/color_Black" android:textSize="20sp" android:textStyle="bold" /> <Button android:id="@+id/btnYES" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="250dp" android:layout_marginTop="120dp" android:background="@color/color_Transparent" android:text="TAKE QUIZ" android:textColor="@color/color_deepBlue" android:textSize="22sp" android:textStyle="bold" /> <Button android:id="@+id/btnNO" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="22dp" android:layout_marginTop="120dp" android:background="@color/color_Transparent" android:text="DECLINE" android:textColor="@color/color_deepBlue" android:textSize="22sp" android:textStyle="bold" /> </RelativeLayout> |
所以问题是我们如何解决错误?
我们应该夸大自定义对话框xml吗?
如您所见,我们试图将声明移到doCustom函数中以查找id // val btnYES = view !!。findViewById(R.id.btnYES)
该链接提供了建议,但我们不知道从哪里开始
链接
正如@Declan Nnadozie已经提到的那样:
同样在Kotlin中,您不需要findViewById即可访问活动的视图。
您可以删除所有以下内容:
1 2 3 4 5 6 | internal lateinit var btnBACK: Button internal lateinit var btnDIALOG: Button internal lateinit var btnYES: Button internal lateinit var btnNO: Button internal lateinit var etStudentName:EditText |
我的建议是使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class PageTwoActivity : AppCompatActivity() { var EnteredText: String ="" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_page_two) addListenerOnButtonBACK() addListenerOnButtonDIALOG() Toast.makeText(this@PageTwoActivity,"You are on Page Two", Toast.LENGTH_LONG).show() } fun doCustom(v: View) { val openDialog = Dialog(this) openDialog.setContentView(R.layout.custom_dialog) val btnYES = openDialog.findViewById<Button>(R.id.btnYES) val btnNO = openDialog.findViewById<Button>(R.id.btnNO) val etStudentName = openDialog.findViewById<EditText>(R.id.etStudentName) openDialog.setCancelable(false) btnYES.setOnClickListener(View.OnClickListener { EnteredText = etStudentName.getText().toString().trim({ it <= ' ' }) if (EnteredText.isEmpty()) { Toast.makeText(applicationContext,"Enter Your Name\ \ OR Click DECLINE", Toast.LENGTH_LONG).show() return@OnClickListener } Toast.makeText(applicationContext,"Registered $EnteredText", Toast.LENGTH_SHORT).show() openDialog.dismiss() }) btnNO.setOnClickListener(View.OnClickListener { EnteredText ="" val intent = Intent(this@PageTwoActivity, MainActivity::class.java) startActivity(intent) openDialog.dismiss() }) openDialog.show() } |
1 | btnYES = findViewById(R.id.btnYES) |
尝试将可为空的视图分配给lateinit非可为空的视图。
所以这是解决方案。
将此
或
将此
您可以采用的一种方法是,不必尝试使用setContentView自定义对话框,而可以使用新的"自定义对话框片段"扩展DialogFragment。然后,您可以像处理片段一样进行处理。您在onCreateDialog中为视图充气,这是我在类似问题中发现的一种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public class PopupAlert extends DialogFragment { TextView heading; TextView popupMessage; Button okBtn; private Runnable onDismissRunnable; private String titleText; private String messageText; private View.OnClickListener positiveListener; public void setOnDismissRunnable(Runnable runnable) { this.onDismissRunnable = runnable; } public void setOkBtnText(String text) { this.okBtnText = text; } public static PopupAlert newInstance(String title, String message) { PopupAlert alert = new PopupAlert(); alert.titleText = title; alert.messageText = message; return alert; } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); if (onDismissRunnable != null) onDismissRunnable.run(); } @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @SuppressLint("InflateParams") View view = LayoutInflater.from(getContext()).inflate(R.layout.view_popup_alert, null); fetchViews(view); builder.setView(view); return builder.create(); } private void fetchViews(View view) { heading = view.findViewById(R.id.popupHeading); popupMessage = view.findViewById(R.id.popupMessage); okBtn = view.findViewById(R.id.okBtn); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); bindToData(); } private void bindToData() { heading.setText(titleText); popupMessage.setText(messageText); okBtn.setOnClickListener((v) -> dismiss()); okBtn.setText(okBtnText); } } |