Snackbar.java revision bfae5eb86f8c5e63b33b6d36073f2230599a716b
1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/*
2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2015 The Android Open Source Project
3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License");
5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License.
6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at
7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *      http://www.apache.org/licenses/LICENSE-2.0
9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software
11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS,
12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and
14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License.
15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage android.support.design.widget;
18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.Context;
20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.res.ColorStateList;
21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.res.TypedArray;
22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Build;
23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Handler;
24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Looper;
25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Message;
26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.annotation.IntDef;
27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.annotation.Nullable;
28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.annotation.StringRes;
29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.design.R;
30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.v4.view.ViewCompat;
31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.text.TextUtils;
33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.util.AttributeSet;
34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.LayoutInflater;
35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.MotionEvent;
36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.View;
37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.ViewGroup;
38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.ViewParent;
39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.animation.Animation;
40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.animation.AnimationUtils;
41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.widget.FrameLayout;
42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.widget.LinearLayout;
43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.widget.TextView;
44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.lang.annotation.Retention;
46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.lang.annotation.RetentionPolicy;
47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport static android.support.design.widget.AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR;
49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/**
51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Snackbars provide lightweight feedback about an operation. They show a brief message at the
52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other
53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * elements on screen and only one can be displayed at a time.
54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p>
55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * They automatically disappear after a timeout or after user interaction elsewhere on the screen,
56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * particularly after interactions that summon a new surface or activity. Snackbars can be swiped
57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * off screen.
58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p>
59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Snackbars can contain an action which is set via
60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * {@link #setAction(CharSequence, android.view.View.OnClickListener)}.
61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * <p>
62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * To be notified when a snackbar has been shown or dismissed, you can provide a {@link Callback}
63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * via {@link #setCallback(Callback)}.</p>
64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class Snackbar {
66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Callback class for {@link Snackbar} instances.
69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @see Snackbar#setCallback(Callback)
71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static abstract class Callback {
73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        /**
74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * Called when the given {@link Snackbar} has been dismissed, either through a time-out,
75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * having been manually dismissed, or an action being clicked.
76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         *
77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * @param snackbar The snackbar which has been dismissed.
78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * @see Snackbar#dismiss()
79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         */
80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public void onDismissed(Snackbar snackbar) {
81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // empty
82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        /**
85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * Called when the given {@link Snackbar} is visible.
86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         *
87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * @param snackbar The snackbar which is now visible.
88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         * @see Snackbar#show()
89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks         */
90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public void onShown(Snackbar snackbar) {
91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // empty
92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @hide
97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @IntDef({LENGTH_SHORT, LENGTH_LONG})
99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Retention(RetentionPolicy.SOURCE)
100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public @interface Duration {}
101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Show the Snackbar for a short period of time.
104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @see #setDuration
106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static final int LENGTH_SHORT = -1;
108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Show the Snackbar for a long period of time.
111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @see #setDuration
113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static final int LENGTH_LONG = 0;
115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final int ANIMATION_DURATION = 250;
117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final int ANIMATION_FADE_DURATION = 180;
118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final Handler sHandler;
120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final int MSG_SHOW = 0;
121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static final int MSG_DISMISS = 1;
122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    static {
124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            @Override
126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            public boolean handleMessage(Message message) {
127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                switch (message.what) {
128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    case MSG_SHOW:
129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        ((Snackbar) message.obj).showView();
130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        return true;
131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    case MSG_DISMISS:
132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        ((Snackbar) message.obj).hideView();
133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        return true;
134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return false;
136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        });
138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final ViewGroup mParent;
141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final Context mContext;
142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final SnackbarLayout mView;
143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private int mDuration;
144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private Callback mCallback;
145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    Snackbar(ViewGroup parent) {
147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mParent = parent;
148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mContext = parent.getContext();
149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        LayoutInflater inflater = LayoutInflater.from(mContext);
151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mView = (SnackbarLayout) inflater.inflate(R.layout.layout_snackbar, mParent, false);
152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Make a Snackbar to display a message
156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * <p>Snackbar will try and find a parent view to hold Snackbar's view from the value given
158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * to {@code view}. Snackbar will walk up the view tree trying to find a suitable parent,
159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * which is defined as a {@link CoordinatorLayout} or the window decor's content view,
160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * whichever comes first.
161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * <p>Having a {@link CoordinatorLayout} in your view hierarchy allows Snackbar to enable
163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * certain features, such as swipe-to-dismiss and automatically moving of widgets like
164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * {@link FloatingActionButton}.
165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param view     The view to find a parent from.
167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param text     The text to show.  Can be formatted text.
168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or {@link
169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *                 #LENGTH_LONG}
170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static Snackbar make(View view, CharSequence text, @Duration int duration) {
172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Snackbar snackbar = new Snackbar(findSuitableParent(view));
173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        snackbar.setText(text);
174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        snackbar.setDuration(duration);
175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return snackbar;
176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Make a Snackbar to display a message.
180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * <p>Snackbar will try and find a parent view to hold Snackbar's view from the value given
182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * to {@code view}. Snackbar will walk up the view tree trying to find a suitable parent,
183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * which is defined as a {@link CoordinatorLayout} or the window decor's content view,
184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * whichever comes first.
185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * <p>Having a {@link CoordinatorLayout} in your view hierarchy allows Snackbar to enable
187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * certain features, such as swipe-to-dismiss and automatically moving of widgets like
188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * {@link FloatingActionButton}.
189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param view     The view to find a parent from.
191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param resId    The resource id of the string resource to use. Can be formatted text.
192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or {@link
193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *                 #LENGTH_LONG}
194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static Snackbar make(View view, int resId, @Duration int duration) {
196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return make(view, view.getResources().getText(resId), duration);
197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Nullable
200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private static ViewGroup findSuitableParent(View view) {
201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        ViewGroup fallback = null;
202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        do {
203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (view instanceof CoordinatorLayout) {
204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                // We've found a CoordinatorLayout, use it
205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return (ViewGroup) view;
206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            } else if (view instanceof FrameLayout) {
207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                if (view.getId() == android.R.id.content) {
208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    // If we've hit the decor content view, then we didn't find a CoL in the
209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    // hierarchy, so use it.
210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    return (ViewGroup) view;
211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                } else {
212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    // It's not the content view but we'll use it as our fallback
213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    fallback = (ViewGroup) view;
214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (view != null) {
218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                // Else, we will loop and crawl up the view hierarchy and try to find a parent
219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                final ViewParent parent = view.getParent();
220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                view = parent instanceof View ? (View) parent : null;
221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } while (view != null);
223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return fallback;
226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Set the action to be displayed in this {@link Snackbar}.
230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param resId    String resource to display
232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param listener callback to be invoked when the action is clicked
233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setAction(@StringRes int resId, View.OnClickListener listener) {
235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return setAction(mContext.getText(resId), listener);
236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Set the action to be displayed in this {@link Snackbar}.
240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param text     Text to display
242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param listener callback to be invoked when the action is clicked
243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setAction(CharSequence text, final View.OnClickListener listener) {
245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final TextView tv = mView.getActionView();
246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (TextUtils.isEmpty(text) || listener == null) {
248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            tv.setVisibility(View.GONE);
249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            tv.setOnClickListener(null);
250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            tv.setVisibility(View.VISIBLE);
252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            tv.setText(text);
253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            tv.setOnClickListener(new View.OnClickListener() {
254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onClick(View view) {
256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    listener.onClick(view);
257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    // Now dismiss the Snackbar
259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    dismiss();
260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            });
262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return this;
264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Sets the text color of the action specified in
268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * {@link #setAction(CharSequence, View.OnClickListener)}.
269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setActionTextColor(ColorStateList colors) {
271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final TextView tv = mView.getActionView();
272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        tv.setTextColor(colors);
273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return this;
274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Sets the text color of the action specified in
278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * {@link #setAction(CharSequence, View.OnClickListener)}.
279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setActionTextColor(int color) {
281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final TextView tv = mView.getActionView();
282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        tv.setTextColor(color);
283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return this;
284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Update the text in this {@link Snackbar}.
288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param message The new text for the Toast.
290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setText(CharSequence message) {
292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final TextView tv = mView.getMessageView();
293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        tv.setText(message);
294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return this;
295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Update the text in this {@link Snackbar}.
299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param resId The new text for the Toast.
301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setText(@StringRes int resId) {
303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return setText(mContext.getText(resId));
304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Set how long to show the view for.
308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @param duration either be one of the predefined lengths:
310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *                 {@link #LENGTH_SHORT}, {@link #LENGTH_LONG}, or a custom duration
311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *                 in milliseconds.
312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public Snackbar setDuration(@Duration int duration) {
314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mDuration = duration;
315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return this;
316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Return the duration.
320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     *
321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @see #setDuration
322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Duration
324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public int getDuration() {
325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mDuration;
326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Returns the {@link Snackbar}'s view.
330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public View getView() {
332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return mView;
333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Show the {@link Snackbar}.
337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public void show() {
339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        SnackbarManager.getInstance().show(mDuration, mManagerCallback);
340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Dismiss the {@link Snackbar}.
344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public void dismiss() {
346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        SnackbarManager.getInstance().dismiss(mManagerCallback);
347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * Set a callback to be called when this the visibility of this {@link Snackbar} changes.
351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public void setCallback(Callback callback) {
353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mCallback = callback;
354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {
357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        @Override
358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public void show() {
359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            sHandler.sendMessage(sHandler.obtainMessage(MSG_SHOW, Snackbar.this));
360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        @Override
363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public void dismiss() {
364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            sHandler.sendMessage(sHandler.obtainMessage(MSG_DISMISS, Snackbar.this));
365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    };
367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    final void showView() {
369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mView.getParent() == null) {
370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            final ViewGroup.LayoutParams lp = mView.getLayoutParams();
371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (lp instanceof CoordinatorLayout.LayoutParams) {
373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                // If our LayoutParams are from a CoordinatorLayout, we'll setup our Behavior
374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                final Behavior behavior = new Behavior();
376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                behavior.setStartAlphaSwipeDistance(0.1f);
377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                behavior.setEndAlphaSwipeDistance(0.6f);
378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    @Override
381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    public void onDismiss(View view) {
382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        dismiss();
383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    }
384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    @Override
386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    public void onDragStateChanged(int state) {
387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        switch (state) {
388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            case SwipeDismissBehavior.STATE_DRAGGING:
389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            case SwipeDismissBehavior.STATE_SETTLING:
390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                // If the view is being dragged or settling, cancel the timeout
391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                SnackbarManager.getInstance().cancelTimeout(mManagerCallback);
392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                break;
393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            case SwipeDismissBehavior.STATE_IDLE:
394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                // If the view has been released and is idle, restore the timeout
395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                SnackbarManager.getInstance().restoreTimeout(mManagerCallback);
396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                break;
397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        }
398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    }
399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                });
400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                ((CoordinatorLayout.LayoutParams) lp).setBehavior(behavior);
401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mParent.addView(mView);
404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (ViewCompat.isLaidOut(mView)) {
407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // If the view is already laid out, animate it now
408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            animateViewIn();
409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Otherwise, add one of our layout change listeners and animate it in when laid out
411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mView.setOnLayoutChangeListener(new SnackbarLayout.OnLayoutChangeListener() {
412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onLayoutChange(View view, int left, int top, int right, int bottom) {
414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    animateViewIn();
415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    mView.setOnLayoutChangeListener(null);
416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            });
418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private void animateViewIn() {
422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            ViewCompat.setTranslationY(mView, mView.getHeight());
424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            ViewCompat.animate(mView).translationY(0f)
425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setDuration(ANIMATION_DURATION)
427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setListener(new ViewPropertyAnimatorListenerAdapter() {
428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        @Override
429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        public void onAnimationStart(View view) {
430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            mView.animateChildrenIn(ANIMATION_DURATION - ANIMATION_FADE_DURATION,
431227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                    ANIMATION_FADE_DURATION);
432227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        }
433227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
434227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        @Override
435227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        public void onAnimationEnd(View view) {
436227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            if (mCallback != null) {
437227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                                mCallback.onShown(Snackbar.this);
438227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            }
439227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            SnackbarManager.getInstance().onShown(mManagerCallback);
440227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        }
441227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    }).start();
442227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
443227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            Animation anim = AnimationUtils.loadAnimation(mView.getContext(), R.anim.snackbar_in);
444227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
445227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setDuration(ANIMATION_DURATION);
446227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setAnimationListener(new Animation.AnimationListener() {
447227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
448227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationEnd(Animation animation) {
449227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    if (mCallback != null) {
450227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        mCallback.onShown(Snackbar.this);
451227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    }
452227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    SnackbarManager.getInstance().onShown(mManagerCallback);
453227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
454227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
455227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
456227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationStart(Animation animation) {}
457227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
458227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
459227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationRepeat(Animation animation) {}
460227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            });
461227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mView.startAnimation(anim);
462227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
463227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
464227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
465227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private void animateViewOut() {
466227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
467227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            ViewCompat.animate(mView).translationY(mView.getHeight())
468227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
469227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setDuration(ANIMATION_DURATION)
470227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    .setListener(new ViewPropertyAnimatorListenerAdapter() {
471227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        @Override
472227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        public void onAnimationStart(View view) {
473227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            mView.animateChildrenOut(0, ANIMATION_FADE_DURATION);
474227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        }
475227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
476227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        @Override
477227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        public void onAnimationEnd(View view) {
478227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                            onViewHidden();
479227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        }
480227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    }).start();
481227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
482227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            Animation anim = AnimationUtils.loadAnimation(mView.getContext(), R.anim.snackbar_out);
483227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
484227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setDuration(ANIMATION_DURATION);
485227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            anim.setAnimationListener(new Animation.AnimationListener() {
486227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
487227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationEnd(Animation animation) {
488227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    onViewHidden();
489227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                }
490227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
491227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
492227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationStart(Animation animation) {}
493227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
494227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                @Override
495227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                public void onAnimationRepeat(Animation animation) {}
496227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            });
497227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mView.startAnimation(anim);
498227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
499227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
500227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
501227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    final void hideView() {
502227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mView.getVisibility() != View.VISIBLE || isBeingDragged()) {
503227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            onViewHidden();
504227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else {
505227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            animateViewOut();
506227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
507227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
508227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
509227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private void onViewHidden() {
510227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // First remove the view from the parent
511227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        mParent.removeView(mView);
512227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // Now call the dismiss listener (if available)
513227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (mCallback != null) {
514227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mCallback.onDismissed(this);
515227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
516227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // Finally, tell the SnackbarManager that it has been dismissed
517227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        SnackbarManager.getInstance().onDismissed(mManagerCallback);
518227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
519227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
520227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
521227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @return if the view is being being dragged or settled by {@link SwipeDismissBehavior}.
522227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
523227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private boolean isBeingDragged() {
524227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final ViewGroup.LayoutParams lp = mView.getLayoutParams();
525227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
526227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (lp instanceof CoordinatorLayout.LayoutParams) {
527227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            final CoordinatorLayout.LayoutParams cllp = (CoordinatorLayout.LayoutParams) lp;
528227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            final CoordinatorLayout.Behavior behavior = cllp.getBehavior();
529227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
530227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (behavior instanceof SwipeDismissBehavior) {
531227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                return ((SwipeDismissBehavior) behavior).getDragState()
532227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        != SwipeDismissBehavior.STATE_IDLE;
533227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
534227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
535227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return false;
536227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
537227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
538227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    /**
539227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     * @hide
540227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks     */
541227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public static class SnackbarLayout extends LinearLayout {
542227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        private TextView mMessageView;
543227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        private TextView mActionView;
544227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
545227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        private int mMaxWidth;
546227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        private int mMaxInlineActionWidth;
547227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
548227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        interface OnLayoutChangeListener {
549227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            public void onLayoutChange(View view, int left, int top, int right, int bottom);
550227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
551227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
552227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        private OnLayoutChangeListener mOnLayoutChangeListener;
553227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
554227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public SnackbarLayout(Context context) {
555227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            this(context, null);
556227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
557227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
558227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        public SnackbarLayout(Context context, AttributeSet attrs) {
559227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            super(context, attrs);
560227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SnackbarLayout);
561227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mMaxWidth = a.getDimensionPixelSize(R.styleable.SnackbarLayout_android_maxWidth, -1);
562227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            mMaxInlineActionWidth = a.getDimensionPixelSize(
563227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                    R.styleable.SnackbarLayout_maxActionInlineWidth, -1);
564227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (a.hasValue(R.styleable.SnackbarLayout_elevation)) {
565227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                ViewCompat.setElevation(this, a.getDimensionPixelSize(
566227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        R.styleable.SnackbarLayout_elevation, 0));
567227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
568            a.recycle();
569
570            setClickable(true);
571
572            // Now inflate our content. We need to do this manually rather than using an <include>
573            // in the layout since older versions of the Android do not inflate includes with
574            // the correct Context.
575            LayoutInflater.from(context).inflate(R.layout.layout_snackbar_include, this);
576        }
577
578        @Override
579        protected void onFinishInflate() {
580            super.onFinishInflate();
581            mMessageView = (TextView) findViewById(R.id.snackbar_text);
582            mActionView = (TextView) findViewById(R.id.snackbar_action);
583        }
584
585        TextView getMessageView() {
586            return mMessageView;
587        }
588
589        TextView getActionView() {
590            return mActionView;
591        }
592
593        @Override
594        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
595            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
596
597            if (mMaxWidth > 0 && getMeasuredWidth() > mMaxWidth) {
598                widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, MeasureSpec.EXACTLY);
599                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
600            }
601
602            final int multiLineVPadding = getResources().getDimensionPixelSize(
603                    R.dimen.snackbar_padding_vertical_2lines);
604            final int singleLineVPadding = getResources().getDimensionPixelSize(
605                    R.dimen.snackbar_padding_vertical);
606            final boolean isMultiLine = mMessageView.getLayout().getLineCount() > 1;
607
608            boolean remeasure = false;
609            if (isMultiLine && mMaxInlineActionWidth > 0
610                    && mActionView.getMeasuredWidth() > mMaxInlineActionWidth) {
611                if (updateViewsWithinLayout(VERTICAL, multiLineVPadding,
612                        multiLineVPadding - singleLineVPadding)) {
613                    remeasure = true;
614                }
615            } else {
616                final int messagePadding = isMultiLine ? multiLineVPadding : singleLineVPadding;
617                if (updateViewsWithinLayout(HORIZONTAL, messagePadding, messagePadding)) {
618                    remeasure = true;
619                }
620            }
621
622            if (remeasure) {
623                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
624            }
625        }
626
627        void animateChildrenIn(int delay, int duration) {
628            ViewCompat.setAlpha(mMessageView, 0f);
629            ViewCompat.animate(mMessageView).alpha(1f).setDuration(duration)
630                    .setStartDelay(delay).start();
631
632            if (mActionView.getVisibility() == VISIBLE) {
633                ViewCompat.setAlpha(mActionView, 0f);
634                ViewCompat.animate(mActionView).alpha(1f).setDuration(duration)
635                        .setStartDelay(delay).start();
636            }
637        }
638
639        void animateChildrenOut(int delay, int duration) {
640            ViewCompat.setAlpha(mMessageView, 1f);
641            ViewCompat.animate(mMessageView).alpha(0f).setDuration(duration)
642                    .setStartDelay(delay).start();
643
644            if (mActionView.getVisibility() == VISIBLE) {
645                ViewCompat.setAlpha(mActionView, 1f);
646                ViewCompat.animate(mActionView).alpha(0f).setDuration(duration)
647                        .setStartDelay(delay).start();
648            }
649        }
650
651        @Override
652        protected void onLayout(boolean changed, int l, int t, int r, int b) {
653            super.onLayout(changed, l, t, r, b);
654            if (changed && mOnLayoutChangeListener != null) {
655                mOnLayoutChangeListener.onLayoutChange(this, l, t, r, b);
656            }
657        }
658
659        void setOnLayoutChangeListener(OnLayoutChangeListener onLayoutChangeListener) {
660            mOnLayoutChangeListener = onLayoutChangeListener;
661        }
662
663        private boolean updateViewsWithinLayout(final int orientation,
664                final int messagePadTop, final int messagePadBottom) {
665            boolean changed = false;
666            if (orientation != getOrientation()) {
667                setOrientation(orientation);
668                changed = true;
669            }
670            if (mMessageView.getPaddingTop() != messagePadTop
671                    || mMessageView.getPaddingBottom() != messagePadBottom) {
672                updateTopBottomPadding(mMessageView, messagePadTop, messagePadBottom);
673                changed = true;
674            }
675            return changed;
676        }
677
678        private static void updateTopBottomPadding(View view, int topPadding, int bottomPadding) {
679            if (ViewCompat.isPaddingRelative(view)) {
680                ViewCompat.setPaddingRelative(view,
681                        ViewCompat.getPaddingStart(view), topPadding,
682                        ViewCompat.getPaddingEnd(view), bottomPadding);
683            } else {
684                view.setPadding(view.getPaddingLeft(), topPadding,
685                        view.getPaddingRight(), bottomPadding);
686            }
687        }
688    }
689
690    final class Behavior extends SwipeDismissBehavior<SnackbarLayout> {
691        @Override
692        public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarLayout child,
693                MotionEvent event) {
694            // We want to make sure that we disable any Snackbar timeouts if the user is
695            // currently touching the Snackbar. We restore the timeout when complete
696            if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
697                switch (event.getActionMasked()) {
698                    case MotionEvent.ACTION_DOWN:
699                        SnackbarManager.getInstance().cancelTimeout(mManagerCallback);
700                        break;
701                    case MotionEvent.ACTION_UP:
702                    case MotionEvent.ACTION_CANCEL:
703                        SnackbarManager.getInstance().restoreTimeout(mManagerCallback);
704                        break;
705                }
706            }
707
708            return super.onInterceptTouchEvent(parent, child, event);
709        }
710    }
711}
712