Я включаю макет в xml для фрагмента. В коде Kotlin для фрагмента я хочу получить доступ к кнопке в макете, чтобы я мог установить прослушиватель onClick. Однако попытка найти кнопку по идентификатору приводит к закрытию приложения. (Я перемещаюсь к фрагменту, используя мою нижнюю навигацию, и приложение просто закрывается. Никаких сообщений об ошибках.) Поиск самого макета по id успешен, потому что регистрация его в виде строки дает «androidx.constraintlayout.widget.ConstraintLayout...» который является родительским тегом макета, который я включаю.
Вот мой упрощенный код:
Макет включен, noteView. 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:id="@+id/noteViewCont">
<ImageButton
android:id="@+id/button"/>
...
Фрагмент. 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:id="@+id/frameLayout">
<FrameLayout
...>
<include
android:id="@+id/noteViewCont"
layout="@layout/noteview"
.../>
<FrameLayout/>
...
(хотя я их там не написал, существуют ограничения для FrameLayout и ImageButton)
My Fragment.kt:
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment, container, false)
val noteVw: View = root.findViewById(R.id.noteViewCont)
Log.v("test", noteVw.toString())
...
val btn: Button = noteVw.findViewById(R.id.button)
...
return root
}
Я ссылался на этот вопрос и пробовал различные решения, предложенные там: findViewById не работает для включения? Ни один не сработал. -Как вы видите, идентификатор включенного файла XML совпадает с идентификатором включения (noteViewCont). -Я попытался настроить noteVw в onViewCreated (), и это ничего не изменило.
Спасибо!
UPDATE
-Я попробовал предложить полностью обойти NoteVw и сделать root.findViewById(R.id.button)
но это ничего не изменило```
Также вот onViewCreated, который я пробовал:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val noteVw: View = view.findViewById(R.id.noteViewCont)
val makeBtn: Button = noteVw.findViewById(R.id.button)
}
2-е ОБНОВЛЕНИЕ
Я понял это, благодаря @ CôngHải. Как только он попросил журнал cra sh, я понял, что, вероятно, должен проверить, что я получаю журнал cra sh, прежде чем я продолжал говорить, что приложение не оставило сообщения «нет сообщения об ошибке». Итак, я нашел эту статью https://www.loginworks.com/blogs/get-crash-logs-android-applications/ и нашел ее в своем журнале sh:
05-04 01:17:43.758 551 551 E AndroidRuntime: java.lang.ClassCastException: androidx.appcompat.widget.AppCompatImageButton cannot be cast to android.widget.Button
Подробности, которые я не включил в этот пост, заключались в том, что я на самом деле использовал ImageButton для представления, которое я пытался сохранить в val button: Button
. Я изменил кнопку на ImageButton, и все работало нормально. Кроме того, первое изменение, предложенное @CôngHải, является хорошим способом упростить код. Вы можете получить доступ к дочернему элементу включенного макета непосредственно из макета, который его включает. Я удалил noteVw и просто использовал root .findViewById, чтобы получить кнопку. Извините, что поднял что-то, что было на самом деле очевидной проблемой, но я надеюсь, что это полезный пример.