• 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.content.Context;
22 import android.util.AttributeSet;
23 import android.view.LayoutInflater;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.widget.FrameLayout;
27 import android.widget.ImageView;
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     /** Icon for the description. */
46     private ImageView mActionDescriptionIcon;
47     /** The clickable view */
48     private View mActionButton;
49     /** Icon for the action button. */
50     private View mActionIcon;
51     /** The view that contains the description. */
52     private TextView mActionDescriptionView;
53     /** The view that contains the text for the action button. */
54     private TextView mActionText;
55     //private ToastBarOperation mOperation;
56 
ActionableToastBar(Context context)57     public ActionableToastBar(Context context) {
58         this(context, null);
59     }
60 
ActionableToastBar(Context context, AttributeSet attrs)61     public ActionableToastBar(Context context, AttributeSet attrs) {
62         this(context, attrs, 0);
63     }
64 
ActionableToastBar(Context context, AttributeSet attrs, int defStyle)65     public ActionableToastBar(Context context, AttributeSet attrs, int defStyle) {
66         super(context, attrs, defStyle);
67         mBottomMarginSizeInConversation = context.getResources().getDimensionPixelSize(
68                 R.dimen.toast_bar_bottom_margin_in_conversation);
69         LayoutInflater.from(context).inflate(R.layout.actionable_toast_row, this, true);
70     }
71 
72     @Override
onFinishInflate()73     protected void onFinishInflate() {
74         super.onFinishInflate();
75 
76         mActionDescriptionIcon = (ImageView) findViewById(R.id.description_icon);
77         mActionDescriptionView = (TextView) findViewById(R.id.description_text);
78         mActionButton = findViewById(R.id.action_button);
79         mActionIcon = findViewById(R.id.action_icon);
80         mActionText = (TextView) findViewById(R.id.action_text);
81     }
82 
83     /**
84      * Tells the view that it will be appearing in the conversation pane
85      * and should adjust its layout parameters accordingly.
86      * @param isInConversationMode true if the view will be shown in the conversation view
87      */
setConversationMode(boolean isInConversationMode)88     public void setConversationMode(boolean isInConversationMode) {
89         final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
90         params.bottomMargin = isInConversationMode ? mBottomMarginSizeInConversation : 0;
91         setLayoutParams(params);
92     }
93 
94     /**
95      * Displays the toast bar and makes it visible. Allows the setting of
96      * parameters to customize the display.
97      * @param listener performs some action when the action button is clicked
98      * @param descriptionIconResourceId resource ID for the description icon or
99      * 0 if no icon should be shown
100      * @param descriptionText a description text to show in the toast bar
101      * @param showActionIcon if true, the action button icon should be shown
102      * @param actionTextResource resource ID for the text to show in the action button
103      * @param replaceVisibleToast if true, this toast should replace any currently visible toast.
104      * Otherwise, skip showing this toast.
105      */
show(final ActionClickedListener listener, int descriptionIconResourceId, CharSequence descriptionText, boolean showActionIcon, int actionTextResource, boolean replaceVisibleToast)106     public void show(final ActionClickedListener listener, int descriptionIconResourceId,
107             CharSequence descriptionText, boolean showActionIcon, int actionTextResource,
108             boolean replaceVisibleToast) {
109 
110         if (!mHidden && !replaceVisibleToast) {
111             return;
112         }
113 
114         mActionButton.setOnClickListener(new OnClickListener() {
115             @Override
116             public void onClick(View widget) {
117                 if (listener != null) {
118                     listener.onActionClicked();
119                 }
120                 hide(true);
121             }
122         });
123 
124         // Set description icon.
125         if (descriptionIconResourceId == 0) {
126             mActionDescriptionIcon.setVisibility(GONE);
127         } else {
128             mActionDescriptionIcon.setVisibility(VISIBLE);
129             mActionDescriptionIcon.setImageResource(descriptionIconResourceId);
130         }
131 
132         mActionDescriptionView.setText(descriptionText);
133         mActionIcon.setVisibility(showActionIcon ? VISIBLE : GONE);
134         mActionText.setText(actionTextResource);
135 
136         mHidden = false;
137         getShowAnimation().start();
138     }
139 
140     /**
141      * Hides the view and resets the state.
142      */
hide(boolean animate)143     public void hide(boolean animate) {
144         // Prevent multiple call to hide.
145         // Also prevent hiding if show animation is going on.
146         if (!mHidden && !getShowAnimation().isRunning()) {
147             mHidden = true;
148             if (getVisibility() == View.VISIBLE) {
149                 mActionDescriptionView.setText("");
150                 mActionButton.setOnClickListener(null);
151                 // Hide view once it's clicked.
152                 if (animate) {
153                     getHideAnimation().start();
154                 } else {
155                     setAlpha(0);
156                     setVisibility(View.GONE);
157                 }
158             }
159         }
160     }
161 
getShowAnimation()162     private Animator getShowAnimation() {
163         if (mShowAnimation == null) {
164             mShowAnimation = AnimatorInflater.loadAnimator(getContext(),
165                     R.anim.fade_in);
166             mShowAnimation.addListener(new Animator.AnimatorListener() {
167                 @Override
168                 public void onAnimationStart(Animator animation) {
169                     setVisibility(View.VISIBLE);
170                 }
171                 @Override
172                 public void onAnimationEnd(Animator animation) {
173                     // There is a tiny change that and hide animation could have finished right
174                     // before the show animation finished.  In that case, the hide will mark the
175                     // view as GONE.  We need to make sure the last one wins.
176                     setVisibility(View.VISIBLE);
177                 }
178                 @Override
179                 public void onAnimationCancel(Animator animation) {
180                 }
181                 @Override
182                 public void onAnimationRepeat(Animator animation) {
183                 }
184             });
185             mShowAnimation.setTarget(this);
186         }
187         return mShowAnimation;
188     }
189 
getHideAnimation()190     private Animator getHideAnimation() {
191         if (mHideAnimation == null) {
192             mHideAnimation = AnimatorInflater.loadAnimator(getContext(),
193                     R.anim.fade_out);
194             mHideAnimation.addListener(new Animator.AnimatorListener() {
195                 @Override
196                 public void onAnimationStart(Animator animation) {
197                 }
198                 @Override
199                 public void onAnimationRepeat(Animator animation) {
200                 }
201                 @Override
202                 public void onAnimationEnd(Animator animation) {
203                     setVisibility(View.GONE);
204                 }
205                 @Override
206                 public void onAnimationCancel(Animator animation) {
207                 }
208             });
209             mHideAnimation.setTarget(this);
210         }
211         return mHideAnimation;
212     }
213 
isEventInToastBar(MotionEvent event)214     public boolean isEventInToastBar(MotionEvent event) {
215         if (!isShown()) {
216             return false;
217         }
218         int[] xy = new int[2];
219         float x = event.getX();
220         float y = event.getY();
221         getLocationOnScreen(xy);
222         return (x > xy[0] && x < (xy[0] + getWidth()) && y > xy[1] && y < xy[1] + getHeight());
223     }
224 
225     /**
226      * Classes that wish to perform some action when the action button is clicked
227      * should implement this interface.
228      */
229     public interface ActionClickedListener {
onActionClicked()230         public void onActionClicked();
231     }
232 }
233