Joshua Rogers
Joshua Rogers

Reputation: 3

Why can't I findViewById the child of a layout included in a fragment's layout?

I include a layout in the xml for a fragment. In the Kotlin code for the fragment, I want to access a button within the layout so I can set its onClick listener. Attempting to find the button by id, however, causes the app to close. (I navigate to the fragment using my bottom navigation, and the app just closes. No error message.) Finding the layout itself by id is successful because logging it as a string gives "androidx.constraintlayout.widget.ConstraintLayout. . ." which is the parent tag of the layout I include.

Here is my code, simplified:

The layout being included, 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"/>
    ...

The fragment.xml layout:

   ...
   <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/>
    ...

(Though I did not write them there, there are constraints for the FrameLayout and 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
    }

I have referred to this question and tried various solutions suggested there: findViewById not working for an include? None have worked. -As you can see, the id of the included XML file is the same as the id of include (noteViewCont). -I tried setting up noteVw in onViewCreated() and that changed nothing.

Thank you!

UPDATE

-I tried a suggestion to basically bypass noteVw entirely and do root.findViewById(R.id.button) but this changed nothing.```

Also, here is the onViewCreated I tried:

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)
    }

2ND UPDATE

I figured it out, thanks to @CôngHải. Once he asked for crash log, I realized I probably should check that I was getting a crash log before I kept saying the app left "no error message". So, I found this article https://www.loginworks.com/blogs/get-crash-logs-android-applications/ and found this in my crash log:

05-04 01:17:43.758   551   551 E AndroidRuntime: java.lang.ClassCastException: androidx.appcompat.widget.AppCompatImageButton cannot be cast to android.widget.Button

A detail I did not include in this post was that I was actually using an ImageButton for the view I was trying to store in val button: Button. I changed Button to ImageButton and everything worked fine. Also, the first change @CôngHải suggested is a good way to simplify the code. You can access the child of an included layout directly from the layout that is including it. I removed noteVw and just used root.findViewById to get the button. Sorry to bring up something that was actually an obvious issue, but I hope this is a useful example.

Upvotes: 0

Views: 269

Answers (1)

C&#244;ng Hải
C&#244;ng Hải

Reputation: 5241

In your XML you define ImageButton but in your code you cast it to Button, It not instance of Button, change to

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

Upvotes: 1

Related Questions