Search code examples
javaandroidandroid-buttonandroid-snackbarfloating-action-button

How to anchor simple button to snackbar


I have button instead of floating action button i want to anchor it with snack bar as it anchor with floating action bar like floating action button moves up when snack bar is shown, with floating action bar we do it like this:

Snackbar.make(fab, s, Snackbar.LENGTH_SHORT);

how can I do with simple button as snackbar and button don't know snackbar presence and vice versa and moves independently

Thanks


Solution

  • You have to attach a Behavior to the View you want to move along with Snakebar movement

    In here I make a custom View and attach the behavior to it

    @CoordinatorLayout.DefaultBehavior(CustomView.Behavior.class)
    public class CustomView extends View {
        public CustomView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public static class Behavior extends CoordinatorLayout.Behavior<CustomView> {
    
            public Behavior() {
                super();
            }
    
            public Behavior(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
    
            @Override
            public void onAttachedToLayoutParams(@NonNull CoordinatorLayout.LayoutParams lp) {
                if (lp.dodgeInsetEdges == Gravity.NO_GRAVITY) {
                    // This setting makes it works (learn from FloatingActionButton.Behavior)
                    lp.dodgeInsetEdges = Gravity.BOTTOM;
                }
            }
    
            @Override
            public boolean onDependentViewChanged(CoordinatorLayout parent, CustomView child,
                                                  View dependency) {
                return false;
            }
        }
    }
    

    Use this CustomView in your layout and it should work

    The FloatingActionButton does the same thing, it has an inner Behavior which do many more things with the shadow padding, show/hide base on AppBarLayout movement. Every movement in CoordinatorLayout base on its Behavior mechanism

    Ref here: http://saulmm.github.io/mastering-coordinator

    P/S: About Snakebar.make usage, pass the CoordinatorLayout into view parameter, don't pass any other components, that will save the system performance. If you look at the Snakebar code, it has a loop, uses the view parameter to find the root view. The root view is what it wants:

    private static ViewGroup findSuitableParent(View view) {
        ViewGroup fallback = null;
        do {
            if (view instanceof CoordinatorLayout) {
                // We've found a CoordinatorLayout, use it
                return (ViewGroup) view;
            } else if (view instanceof FrameLayout) {
                if (view.getId() == android.R.id.content) {
                    // If we've hit the decor content view, then we didn't find a CoL in the
                    // hierarchy, so use it.
                    return (ViewGroup) view;
                } else {
                    // It's not the content view but we'll use it as our fallback
                    fallback = (ViewGroup) view;
                }
            }
    
            if (view != null) {
                // Else, we will loop and crawl up the view hierarchy and try to find a parent
                final ViewParent parent = view.getParent();
                view = parent instanceof View ? (View) parent : null;
            }
        } while (view != null);
    
        // If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
        return fallback;
    }