0

In my Android app, I am trying to show a Snackbar above a toolbar item by using setAnchorView(toolbar). I create and show the Snackbar shortly after launching my Activity. It works around 33% of the time - the rest of the time, the Snackbar displays from the bottom of the screen (as if setAnchorView were never called) How can I get it to work 100% of the time?

I only have this random display issue when showing Snackbars at the start of the Activity. When showing other Snackbars with setAnchorView after the activity has been running for several seconds, it always works as expected and displays above the toolbar.

Here's some example code:

        View v = findViewById(R.id.main_relative_layout);
        Snackbar sn = Snackbar.make(v, R.string.snackbar_info_starting, Snackbar.LENGTH_SHORT);
        sn.setAnchorView(R.id.toolbar);
        sn.show();

I observed the same behavior in com.google.android.material:material:1.3.0 (the current latest version) and 1.2.0.

I tried adding some debug statements to verify if the toolbar object existed. I suspected that maybe the object was null when I ran into this issue while calling setAnchorView. My guess was incorrect: the Toolbar object was always created and non-null whether or not it worked correctly. Here's the object String representation: android.widget.LinearLayout{2e0f901 V.E...... ......ID 0,0-0,0 #7f080237 app:id/toolbar}

Any suggestions? My suspicion is that the toolbar UI element is not in a "ready" state to be used by setAnchorView, but I don't possess enough Android knowledge to diagnose or work around such an issue.

curious_george
  • 622
  • 2
  • 8
  • 19

1 Answers1

0

I think I figured out a workaround using information from another question: How can you tell when a layout has been drawn?

I now suspect the toolbar was not fully drawn out - I can see that toolbar's getY() is always "0" when calling it immediately after the activity launches. (However, sometimes the Snackbar displays in the correct location even when toolbar's getY() is 0!).

Working on this assumption, I used this code to only show the Snackbar after the toolbar has been drawn:

View toolbar = findViewById(R.id.toolbar);
toolbar.post( new Runnable() {
    @Override
    public void run() {
      View v = findViewById(R.id.main_relative_layout);
      Snackbar sn = Snackbar.make(v,
                                  R.string.snackbar_info_starting, 
                                  Snackbar.LENGTH_SHORT);
      sn.setAnchorView(R.id.toolbar);
      sn.show();
    }
  });

After implementing this, I have not been able to reproduce the issue.

curious_george
  • 622
  • 2
  • 8
  • 19