'How to find a view for Snackbar in fragment's onCreateView method if I use view binding and navigation component?

I'm trying to show a snack bar in fragment's onCreateView method but I don't know what view to passing inside the snack bar. I'm very confused because I first time use the Navigation component and view binding and maybe is there a problem. I tried binding.root but I got this exception:

java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.

After that I tried requireView().rootView as parameter but I also got this exception:

java.lang.IllegalStateException: Fragment XFragment{7a091b5} (cefa1aef-59c3-4602-bcf1-b36f7d538cf9) id=0x7f0800f7} did not return a View from onCreateView() or this was called before onCreateView()

MY CODE IN XFragment:

package com.sdsd.sds

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.Navigation
import com.google.android.material.snackbar.Snackbar

import com.sdsd.sds.databinding.FragmentXBinding

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"


class XFragment : Fragment() {

    private var _binding: FragmenXBinding? = null
    private val binding get() = _binding!!


    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentXBinding.inflate(inflater, container, false)
        binding.tvFgRegistration.setOnClickListener {
            Navigation.findNavController(binding.root)
                .navigate(R.id.action_f1_to_f2)
        }

        

        val snackbar: Snackbar = Snackbar.make(binding.root, "Succesful", Snackbar.LENGTH_LONG)
        snackbar.show()


        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }


    companion object {

        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            XFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

XML LAYOUT FILE:

    <?xml version="1.0" encoding="utf-8"?>
    <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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/ic"
        tools:context=".XFragment">
    
       
        <EditText
            android:id="@+id/etE"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:background="@color/translucent"
            android:drawableStart="@drawable/ic_vector"
            android:drawablePadding="5dp"
            android:ems="10"
            android:hint="@string/e_mail"
            android:inputType="text"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />
    
        <EditText
            android:id="@+id/etP"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:background="@color/translucent"
            android:drawableStart="@drawable/ic_vector"
            android:drawablePadding="5dp"
            android:ems="10"
            android:hint="@string/password"
            android:inputType="textPassword"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/etE" />
    
          
        <TextView
            android:id="@+id/tvFgRegistration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="180dp"
            android:layout_marginEnd="76dp"
            android:layout_marginBottom="100dp"
            android:text="@string/new_u"
            android:textColor="@color/white"
            android:textSize="18sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

I only want to show a snack bar with a message when XFragment creates.

Can anyone tell me how to solve this and explain me in a few words why?



Solution 1:[1]

I found a simple solution and seems a Snackbar works excellent only with CoordinatorLayout as root layout so I set CoordinatorLayout as my root layout in the XML file.

In the Snackbar I just put binding.coordinatorlayout where coordinatorlayout is just an id of CoordinatorLayout in the XML file.

Code solution for a fragment is here:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentXBinding.inflate(inflater, container, false)
        binding.tvFgRegistration.setOnClickListener {
            Navigation.findNavController(binding.root)
                .navigate(R.id.action_f1_to_f2)
        }

        val snackbar: Snackbar = Snackbar.make(binding.coordinatorlayout, "Succesful", Snackbar.LENGTH_LONG)
        snackbar.show()


        return binding.root
    }

XML layout file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    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/coordinatorlayout" //ID OF COORDINATOR LAYOUT
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic"
    tools:context=".XFragment" >

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ic_backg">

  <EditText
            android:id="@+id/etE"
            android:layout_width="0dp"
      .
      .
      .


</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Solution 2:[2]

I found few ways to show a snack bar from a fragment

One of the solution is to use requireView().

Snackbar.make(
            requireView(),
            "Hello from Snackbar",
            Snackbar.LENGTH_SHORT
        ).show()

This solution will work when you are inside any onClickListner{} you can simply pass it as a view and it will do the job.

    binding.button.setOnClickListener {
       Snackbar.make(
                it,
                "Hello from Snackbar",
                Snackbar.LENGTH_SHORT
            ).show()
}

Solution 3:[3]

I faced the same issue while using navigation architecture.

What worked for me was

if(isAdded){
Snackbar.make(requireActivity.window.decorView.rootView,"message").show()
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dezo
Solution 2 BlankSpace
Solution 3 return 0