Почему я не могу найти ViewById дочерний элемент макета, включенного в макет фрагмента? - PullRequest
0 голосов
/ 04 мая 2020

Я включаю макет в 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, чтобы получить кнопку. Извините, что поднял что-то, что было на самом деле очевидной проблемой, но я надеюсь, что это полезный пример.

1 Ответ

1 голос
/ 04 мая 2020

В вашем XML вы определяете ImageButton, но в своем коде вы преобразуете его в Button, а не в экземпляр Button, измените на

val makeBtn: ImageButton = noteVw.findViewById(R.id.button)
...