findViewById выдает нулевое исключение, когда он используется в виджетах диалогового окна оповещения

#android #android-studio #kotlin #android-alertdialog #findviewbyid

#Android #android-studio #kotlin #android-alertdialog #findviewbyid

Вопрос:

У меня есть настраиваемый диалог оповещения layout_dialog.xml , activity_main.xml и MainActivivty.kt я пытаюсь использовать findViewById() in MainActivity.kt для получения кнопки и TextView из диалогового окна оповещения. вот часть моего кода :

 tv7 = findViewById(R.id.tv7)
bt4 = findViewById(R.id.bt4)
  

Но я получаю следующее исключение:

 java.lang.NullPointerException: findViewById(R.id.tv7) must not be null
  

вот полное сообщение об ошибке :

 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.wordschain, PID: 8398
java.lang.NullPointerException: findViewById(R.id.tv7) must not be null
    at com.example.wordschain.MainActivity.create_Alert_Dialog(MainActivity.kt:83)
    at com.example.wordschain.MainActivity.do1(MainActivity.kt:318)
    at com.example.wordschain.MainActivity$onCreate$1.onClick(MainActivity.kt:48)
    at android.view.View.performClick(View.java:6329)
    at android.view.View$PerformClick.run(View.java:25002)
    at android.os.Handler.handleCallback(Handler.java:809)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7555)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
  

Примечание: я получаю эти сообщения в режиме отладки.

РЕДАКТИРОВАТЬ: здесь я делюсь layout_dialog.xml фрагментом:

 <?xml version="1.0" encoding="utf-8"?>
  
 <data />

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:background="@color/white">

    <TextView
        android:id="@ id/tv7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="You lost with score"
        android:background="@color/Red2"
        android:textSize="40sp"
        android:layout_centerHorizontal="true" />

    <Button
        android:id="@ id/bt4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv7"
        android:layout_centerHorizontal="true"
        android:text="Restart"
        android:textSize="20sp"
        android:layout_marginTop="15dp" />

    <TextView
        android:id="@ id/tv8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/bt4"
        android:layout_centerHorizontal="true"
        android:text="Or watch an Ad and continue with 2 chances"
        android:textSize="18sp"
        android:textColor="@color/Black"
        android:layout_marginTop="15dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv8"
        android:layout_centerHorizontal="true"
        android:text="Watch Ad"
        android:textSize="20sp"
        android:layout_marginTop="15dp" />

</RelativeLayout>
  

и вот где я использовал findViewById() в основном действии:

 class MainActivity : AppCompatActivity() {
    //Some code ....
    override fun onCreate(savedInstanceState: Bundle?) {
        //Some code ...
        }
    fun create_Alert_Dialog(How: Int){
    //Alert dialog builder
    val messageBoxView = LayoutInflater.from(this).inflate(R.layout.layout_dialog,null)
    //Alert dialog builder
    val messageBoxBuilder = AlertDialog.Builder(this).setView(messageBoxView)
    //Setting undissmissable
    messageBoxBuilder.setCancelable(false)
    //Show
    messageBoxBuilder.show()
    tv7 = findViewById(R.id.tv7)
    bt4 = findViewById(R.id.bt4)
    bt4.setOnClickListener { Lose() }
}
  

Комментарии:

1. сообщение layout_dialog.xml код и фрагмент кода, из которого вы вызываете tv7 = findViewById(R.id.tv7)

2. Поделитесь своим файлом макета и фрагментом кода

3. Я поделился ими и (Примечание: я использую привязку данных в activity_main.xml )

4. Интересно, как компилируется этот код!

5. В моем приложении более 400 строк кода, я не могу поделиться ими всеми здесь, они просто сделают все медленнее и сложнее, я только что опубликовал соответствующую часть кода

Ответ №1:

Замените это:

 tv7 = findViewById(R.id.tv7)
bt4 = findViewById(R.id.bt4)
  

С помощью этого:

 tv7 = messageBoxView.findViewById(R.id.tv7)
bt4 = messageBoxView.findViewById(R.id.bt4)
  

Вы раздуваете представление (диалоговое окно) в свою деятельность с помощью:

 val messageBoxView = LayoutInflater.from(this).inflate(R.layout.layout_dialog, null)
  

Затем вам нужно определить представления tv7 и bt4, но они находятся в представлении, которое вы раздули ранее. Поэтому вам нужно определить их на основе раздутого представления.

Ответ №2:

Элемент с идентификатором tv7 не находится внутри действия, он присутствует в представлении диалоговых окон. messageBoxView — это расширенное представление ваших диалогов. Поэтому любое представление, к которому вы хотите получить доступ внутри этого макета, должно находиться под его ссылкой.

tv7 = messageBoxView.findViewById(R.id.tv7)

bt4 = messageBoxView.findViewById(R.id.bt4)