0

I have a Fragment class and a normal HelpFunctionsclass. I want the Fragment class to show a Snackbar by calling a method in the HelpFunctionsclass.

In the Fragment class I call the following code after a certain button has been pressed:

HelpFunctions.showSnackBar(getActivity(), getString(R.string.message_ratingSubmittedNotSuccessfully),  binding.getRoot());

And in the HelpFunctions class the method for displaying the Snackbar looks like this:

public static void showSnackBar(Activity activity, String message, View root){

    Snackbar currentSnackBar = Snackbar.make( root, message, Snackbar.LENGTH_LONG);
    View sbView = currentSnackBar.getView();
    sbView.setBackgroundColor(ContextCompat.getColor(activity, R.color.colorBlue));
    currentSnackBar.show();
}

When I execute my code I get the following error message "java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.". I looked for a solution to this problem and found this answer: java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view. Here it is stated that I should use findViewById(android.R.id.content) for the root. Unfortunately, when I use this in my method showSnackBar in the line Snackbar currentSnackBar = Snackbar.make( findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG); I get the error message from the compiler "Cannot resolve method 'findViewById' in 'HelpFunctions'".

Any idea why I am getting this error message and why I can't change it with findViewById? How else can I show a Snackbar?

VanessaF
  • 515
  • 11
  • 36
  • `findViewById()` is a method on `Activity` and `View`. Most likely, the `findViewById(android.R.id.content)` call is to be made on your `Activity`. What you really should be passing in is some child of a `CoordinatorLayout`. This is covered in [the documentation for `Snackbar.make()`](https://developer.android.com/reference/com/google/android/material/snackbar/Snackbar?hl=en#make(android.view.View,%20java.lang.CharSequence,%20int)). – CommonsWare Jul 30 '22 at 15:08
  • The solution may be to use Snackbar.make(context, view, text, duration) Because you are using it outside the View layer, you need to pass the context. – Emmanuel Conradie Jul 30 '22 at 15:10
  • @CommonsWare: Thanks for your answer. I tried to use `findViewById` in my Fragment class (which is a UI class) and there I get the same error. Further, in the documentation of Snackbar you see, that it expects a View. By using `binding.getRoot()` as an argument I pass a view to it as you can read in the official documentation of ViewBinding (https://developer.android.com/topic/libraries/view-binding). So I don't understand why this error occurs with the Illegal Argument – VanessaF Jul 30 '22 at 15:16
  • @EmmanuelConradie: Thanks for your answer. The question is what is the context and how can I create and pass it? Furthermore, there is a constructor in SnackBar that does not need any context and I try to use this one with 3 arguments that I pass to it. Unforunately I still get the error message. – VanessaF Jul 30 '22 at 15:18
  • @VanessaF you already have the context, it is the activity you are passing – Emmanuel Conradie Jul 30 '22 at 15:19
  • @EmmanuelConradie: What is then the view? I thought the activity is the view? Or shall it serve as both the view and the context? – VanessaF Jul 30 '22 at 15:20
  • @VanessaF Try the updated answer – Emmanuel Conradie Jul 30 '22 at 15:22
  • @EmmanuelConradie: Does not work. Yields the same error. – VanessaF Jul 30 '22 at 15:36
  • @VanessaF could you please specify which line you are getting the error on? Because I don't think the problem is the currentSnackbar. I think it is when you are trying to get the snackbar view – Emmanuel Conradie Jul 30 '22 at 15:39
  • Have you made sure your root view has loaded correctly before passing it? – Emmanuel Conradie Jul 30 '22 at 15:47
  • @EmmanuelConradie: How can I make sure that the root view has loaded correctly? I just use the following command `binding.getRoot()` and that should actually do it. What else can I do? – VanessaF Jul 30 '22 at 15:48
  • @VanessaF please post the code of how you are loading your view and where you are calling show snackbar – Emmanuel Conradie Jul 30 '22 at 15:50
  • @EmmanuelConradie: Unforunately the code is quite long (more than 1000 lines). So I don't think it makes sense to post it. But do you know what I can do to ensure that the"root view has loaded correctly before passing it" as you wrote? The error comes from the line `Snackbar currentSnackBar = Snackbar.make( activity, root, message, Snackbar.LENGTH_LONG);`. I don't think that I need an activity here because on other occasions in the app I never use the activity and so far everything has been okay. Strangely in this case this IllegalArgumentException occurs and I don't know why. Any suggestions? – VanessaF Jul 30 '22 at 16:12
  • @VanessaF your first problem is that your view class is 1000 lines long. Your view should not contain any logic. Call showSnackbar right after you called onBind(view) – Emmanuel Conradie Jul 30 '22 at 16:16
  • @VanessaF I do not know in which method you are binding or inflating your view so without code I cannot help you – Emmanuel Conradie Jul 30 '22 at 16:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/246924/discussion-between-vanessaf-and-emmanuel-conradie). – VanessaF Jul 31 '22 at 07:36

1 Answers1

0

As stated in the documentation.

Snackbar will try and find a parent view to hold Snackbar's view from the value given to view. Snackbar will walk up the view tree trying to find a suitable parent, which is defined as a CoordinatorLayout or the window decor's content view, whichever comes first.

You need to now provide context direct the view up the hierarchy

Context: The context to use to create the Snackbar view.

Therefore use Snackbar.make(Context context, View view, CharSequence text, int duration)

Pass it like

public static void showSnackBar(Activity activity, String message, View root){
    Snackbar currentSnackBar = Snackbar.make( activity, root, message, Snackbar.LENGTH_LONG);
}
Emmanuel Conradie
  • 345
  • 1
  • 5
  • 20
  • Thanks Emmanuel for your answer. Unfortunately your suggested code leads to the same error message "java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view." – VanessaF Jul 30 '22 at 15:29
  • Hi, actually this line throws the error `Snackbar currentSnackBar = Snackbar.make( activity, root, message, Snackbar.LENGTH_LONG);` – VanessaF Jul 30 '22 at 15:47