• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.deskclock.widget;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorInflater;
21 import android.animation.AnimatorListenerAdapter;
22 import android.content.Context;
23 import android.util.AttributeSet;
24 import android.view.LayoutInflater;
25 import android.view.MotionEvent;
26 import android.view.View;
27 import android.widget.FrameLayout;
28 import android.widget.LinearLayout;
29 import android.widget.TextView;
30 
31 import com.android.deskclock.R;
32 
33 /**
34  * A custom {@link View} that exposes an action to the user.
35  * <p>
36  * This is a copy of packages/apps/UnifiedEmail/src/com/android/mail/ui/ActionableToastBar.java
37  * with minor modifications.
38  */
39 public class ActionableToastBar extends LinearLayout {
40     private boolean mHidden = false;
41     private Animator mShowAnimation;
42     private Animator mHideAnimation;
43     private final int mBottomMarginSizeInConversation;
44 
45     /** The clickable view */
46     private View mActionButton;
47     /** The view that contains the description. */
48     private TextView mActionDescriptionView;
49     /** The view that contains the text for the action button. */
50     private TextView mActionText;
51     //private ToastBarOperation mOperation;
52 
ActionableToastBar(Context context)53     public ActionableToastBar(Context context) {
54         this(context, null);
55     }
56 
ActionableToastBar(Context context, AttributeSet attrs)57     public ActionableToastBar(Context context, AttributeSet attrs) {
58         this(context, attrs, 0);
59     }
60 
ActionableToastBar(Context context, AttributeSet attrs, int defStyle)61     public ActionableToastBar(Context context, AttributeSet attrs, int defStyle) {
62         super(context, attrs, defStyle);
63         mBottomMarginSizeInConversation = context.getResources().getDimensionPixelSize(
64                 R.dimen.toast_bar_bottom_margin_in_conversation);
65         LayoutInflater.from(context).inflate(R.layout.actionable_toast_row, this, true);
66     }
67 
68     @Override
onFinishInflate()69     protected void onFinishInflate() {
70         super.onFinishInflate();
71 
72         mActionDescriptionView = (TextView) findViewById(R.id.description_text);
73         mActionButton = findViewById(R.id.action_button);
74         mActionText = (TextView) findViewById(R.id.action_text);
75     }
76 
77     /**
78      * Tells the view that it will be appearing in the conversation pane
79      * and should adjust its layout parameters accordingly.
80      * @param isInConversationMode true if the view will be shown in the conversation view
81      */
setConversationMode(boolean isInConversationMode)82     public void setConversationMode(boolean isInConversationMode) {
83         final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
84         params.bottomMargin = isInConversationMode ? mBottomMarginSizeInConversation : 0;
85         setLayoutParams(params);
86     }
87 
88     /**
89      * Displays the toast bar and makes it visible. Allows the setting of
90      * parameters to customize the display.
91      * @param listener performs some action when the action button is clicked
92      * @param descriptionIconResourceId resource ID for the description icon or
93      * 0 if no icon should be shown
94      * @param descriptionText a description text to show in the toast bar
95      * @param showActionIcon if true, the action button icon should be shown
96      * @param actionTextResource resource ID for the text to show in the action button
97      * @param replaceVisibleToast if true, this toast should replace any currently visible toast.
98      * Otherwise, skip showing this toast.
99      */
show(final ActionClickedListener listener, int descriptionIconResourceId, CharSequence descriptionText, boolean showActionIcon, int actionTextResource, boolean replaceVisibleToast)100     public void show(final ActionClickedListener listener, int descriptionIconResourceId,
101             CharSequence descriptionText, boolean showActionIcon, int actionTextResource,
102             boolean replaceVisibleToast) {
103 
104         if (!mHidden && !replaceVisibleToast) {
105             return;
106         }
107 
108         mActionButton.setOnClickListener(new OnClickListener() {
109             @Override
110             public void onClick(View widget) {
111                 if (listener != null) {
112                     listener.onActionClicked();
113                 }
114                 hide(true);
115             }
116         });
117 
118         mActionDescriptionView.setText(descriptionText);
119         mActionText.setText(actionTextResource);
120 
121         mHidden = false;
122         getShowAnimation().start();
123     }
124 
125     /**
126      * Hides the view and resets the state.
127      */
hide(boolean animate)128     public void hide(boolean animate) {
129         // Prevent multiple call to hide.
130         // Also prevent hiding if show animation is going on.
131         if (!mHidden && !getShowAnimation().isRunning()) {
132             mHidden = true;
133             if (getVisibility() == View.VISIBLE) {
134                 mActionDescriptionView.setText("");
135                 mActionButton.setOnClickListener(null);
136                 // Hide view once it's clicked.
137                 if (animate) {
138                     getHideAnimation().start();
139                 } else {
140                     setAlpha(0);
141                     setVisibility(View.GONE);
142                 }
143             }
144         }
145     }
146 
getShowAnimation()147     private Animator getShowAnimation() {
148         if (mShowAnimation == null) {
149             mShowAnimation = AnimatorInflater.loadAnimator(getContext(), R.animator.fade_in);
150             mShowAnimation.addListener(new AnimatorListenerAdapter() {
151                 @Override
152                 public void onAnimationStart(Animator animation) {
153                     setVisibility(View.VISIBLE);
154                 }
155 
156                 @Override
157                 public void onAnimationEnd(Animator animation) {
158                     // There is a tiny change that and hide animation could have finished right
159                     // before the show animation finished.  In that case, the hide will mark the
160                     // view as GONE.  We need to make sure the last one wins.
161                     setVisibility(View.VISIBLE);
162                 }
163             });
164             mShowAnimation.setTarget(this);
165         }
166         return mShowAnimation;
167     }
168 
getHideAnimation()169     private Animator getHideAnimation() {
170         if (mHideAnimation == null) {
171             mHideAnimation = AnimatorInflater.loadAnimator(getContext(), R.animator.fade_out);
172             mHideAnimation.addListener(new AnimatorListenerAdapter() {
173                 @Override
174                 public void onAnimationEnd(Animator animation) {
175                     setVisibility(View.GONE);
176                 }
177             });
178             mHideAnimation.setTarget(this);
179         }
180         return mHideAnimation;
181     }
182 
isEventInToastBar(MotionEvent event)183     public boolean isEventInToastBar(MotionEvent event) {
184         if (!isShown()) {
185             return false;
186         }
187         int[] xy = new int[2];
188         float x = event.getX();
189         float y = event.getY();
190         getLocationOnScreen(xy);
191         return (x > xy[0] && x < (xy[0] + getWidth()) && y > xy[1] && y < xy[1] + getHeight());
192     }
193 
194     /**
195      * Classes that wish to perform some action when the action button is clicked
196      * should implement this interface.
197      */
198     public interface ActionClickedListener {
onActionClicked()199         public void onActionClicked();
200     }
201 }
202