2727/**
2828 * See <a href="http://getbootstrap.com/components/#badges>http://getbootstrap.com/components/#alerts</a>
2929 */
30- public class BootstrapAlert extends RelativeLayout {
30+ @ BetaApi
31+ public class BootstrapAlert extends RelativeLayout implements Animation .AnimationListener {
32+
33+ /**
34+ * Provides methods which receive callbacks in response to changes in the view visibility.
35+ */
36+ public interface VisibilityChangeListener {
37+
38+ /**
39+ * Called when the alert is set to be dismissed with an animation.
40+ * @param alert the alert
41+ */
42+ void onAlertDismissStarted (BootstrapAlert alert );
43+
44+ /**
45+ * Called when the alert is no longer visible.
46+ * @param alert the alert
47+ */
48+ void onAlertDismissCompletion (BootstrapAlert alert );
49+
50+ /**
51+ * Called when the alert set to appear with an animation
52+ * @param alert the alert
53+ */
54+ void onAlertAppearStarted (BootstrapAlert alert );
55+
56+ /**
57+ * Called when the alert is now visible.
58+ * @param alert the alert
59+ */
60+ void onAlertAppearCompletion (BootstrapAlert alert );
61+ }
3162
3263 private ImageView closeButton ;
3364
@@ -42,10 +73,9 @@ public class BootstrapAlert extends RelativeLayout {
4273 private AlphaAnimation fadeInAnimation ;
4374 private AlphaAnimation fadeOutAnimation ;
4475
45- private boolean dismissible ;
46- private boolean hidden ;
76+ private boolean userDismissible ;
4777
48- private OnDismissListener onDismissListener ;
78+ private VisibilityChangeListener visibilityChangeListener ;
4979
5080 private static final AtomicInteger nextGeneratedId = new AtomicInteger (1 );
5181
@@ -74,7 +104,8 @@ private void initialise(AttributeSet attrs) {
74104
75105 strongText = a .getString (R .styleable .BootstrapAlert_strongText );
76106 messageText = a .getString (R .styleable .BootstrapAlert_messageText );
77- dismissible = a .getBoolean (R .styleable .BootstrapAlert_dismissible , false );
107+ userDismissible = a .getBoolean (R .styleable .BootstrapAlert_dismissible , false );
108+
78109 if (strongText == null ) {
79110 strongText = "" ;
80111 }
@@ -90,13 +121,14 @@ private void initialise(AttributeSet attrs) {
90121 R .dimen .bootstrap_button_default_font_size );
91122 baselinePadding = DimenUtils .pixelsFromDpResource (getContext (),
92123 R .dimen .bootstrap_alert_paddings );
93-
124+ setupAnimations ();
94125 updateBootstrapState ();
95126 }
96127
97128 private void updateBootstrapState () {
98129 TextView alertText = new TextView (getContext ());
99130 closeButton = new ImageView (getContext ());
131+
100132 if (Build .VERSION .SDK_INT < Build .VERSION_CODES .JELLY_BEAN_MR1 ) {
101133 alertText .setId (generateViewUniqueId ());
102134 closeButton .setId (generateViewUniqueId ());
@@ -105,37 +137,7 @@ private void updateBootstrapState() {
105137 alertText .setId (View .generateViewId ());
106138 closeButton .setId (View .generateViewId ());
107139 }
108- fadeInAnimation = new AlphaAnimation (0.0f , 1.0f );
109- fadeInAnimation .setDuration (300 );
110- fadeInAnimation .setInterpolator (new AccelerateInterpolator ());
111- fadeOutAnimation = new AlphaAnimation (1.0f , 0.0f );
112- fadeOutAnimation .setDuration (300 );
113- fadeOutAnimation .setInterpolator (new AccelerateInterpolator ());
114-
115- fadeInAnimation .setAnimationListener (new Animation .AnimationListener () {
116- @ Override
117- public void onAnimationStart (Animation animation ) {setVisibility (VISIBLE );}
118-
119- @ Override
120- public void onAnimationEnd (Animation animation ) {}
121-
122- @ Override
123- public void onAnimationRepeat (Animation animation ) {}
124- });
125-
126- fadeOutAnimation .setAnimationListener (new Animation .AnimationListener () {
127- @ Override
128- public void onAnimationStart (Animation animation ) {}
129140
130- @ Override
131- public void onAnimationEnd (Animation animation ) {
132- setVisibility (GONE );
133- if (onDismissListener != null ) { onDismissListener .onDismiss (); }
134- }
135-
136- @ Override
137- public void onAnimationRepeat (Animation animation ) {}
138- });
139141
140142 LayoutParams textParams = new LayoutParams (LayoutParams .MATCH_PARENT ,
141143 LayoutParams .WRAP_CONTENT );
@@ -165,7 +167,8 @@ public void onAnimationRepeat(Animation animation) {}
165167 ViewUtils .setBackgroundDrawable (this , bg );
166168
167169 addView (alertText );
168- if (dismissible ) {
170+
171+ if (userDismissible ) {
169172 addView (closeButton );
170173 ((View ) closeButton .getParent ()).post (new Runnable () {
171174 @ Override
@@ -185,7 +188,7 @@ public void run() {
185188 closeButton .setOnClickListener (new OnClickListener () {
186189 @ Override
187190 public void onClick (View v ) {
188- hide ( );
191+ dismiss ( true );
189192 }
190193 });
191194 }
@@ -195,22 +198,74 @@ public void onClick(View v) {
195198 setPadding (hori , vert , hori , vert );
196199 }
197200
198- public void hide () {
199- hidden = true ;
200- startAnimation (fadeOutAnimation );
201+ private void setupAnimations () {
202+ fadeInAnimation = new AlphaAnimation (0.0f , 1.0f );
203+ fadeInAnimation .setDuration (300 );
204+ fadeInAnimation .setInterpolator (new AccelerateInterpolator ());
205+ fadeInAnimation .setAnimationListener (this );
206+
207+ fadeOutAnimation = new AlphaAnimation (1.0f , 0.0f );
208+ fadeOutAnimation .setDuration (300 );
209+ fadeOutAnimation .setInterpolator (new AccelerateInterpolator ());
210+ fadeOutAnimation .setAnimationListener (this );
201211 }
202212
203- public void show () {
204- hidden = false ;
205- startAnimation (fadeInAnimation );
213+ /**
214+ * Hides the alert with an animation, setting its visibility to {@link View#GONE}
215+ * @param animated whether the dismissal should be animated or not
216+ */
217+ public void dismiss (boolean animated ) {
218+ if (animated ) {
219+ if (visibilityChangeListener != null ) {
220+ visibilityChangeListener .onAlertDismissStarted (this );
221+ }
222+ startAnimation (fadeOutAnimation );
223+ }
224+ else {
225+ setVisibility (GONE );
226+ }
206227 }
207228
208- public boolean isHidden () {
209- return hidden ;
229+ /**
230+ * Shows the alert with an animation, setting its visibility to {@link View#VISIBLE}
231+ * @param animated whether the appearance should be animated or not
232+ */
233+ public void show (boolean animated ) {
234+ if (animated ) {
235+ if (visibilityChangeListener != null ) {
236+ visibilityChangeListener .onAlertAppearStarted (this );
237+ }
238+ startAnimation (fadeInAnimation );
239+ }
240+ else {
241+ setVisibility (VISIBLE );
242+ }
243+ }
244+
245+ /**
246+ * Retrieves whether the user can dismiss the dialog or not
247+ * @return true if dismissable
248+ */
249+ public boolean isUserDismissible () {
250+ return userDismissible ;
251+ }
252+
253+ /**
254+ * Sets whether the user can dismiss the dialog or not.
255+ * @param userDismissible true if dismissable
256+ */
257+ public void setUserDismissible (boolean userDismissible ) {
258+ this .userDismissible = userDismissible ;
259+ updateBootstrapState ();
210260 }
211261
212- public void setOnDismissListener (OnDismissListener onDismissListener ) {
213- this .onDismissListener = onDismissListener ;
262+ /**
263+ * Sets a {@link VisibilityChangeListener} that will be notified on changes
264+ *
265+ * @param visibilityChangeListener the listener
266+ */
267+ public void setVisibilityChangeListener (VisibilityChangeListener visibilityChangeListener ) {
268+ this .visibilityChangeListener = visibilityChangeListener ;
214269 }
215270
216271 private int generateViewUniqueId () {
@@ -227,7 +282,43 @@ private int generateViewUniqueId() {
227282 }
228283 }
229284
230- public interface OnDismissListener {
231- void onDismiss ();
285+ @ Override
286+ public void setVisibility (int visibility ) {
287+ super .setVisibility (visibility );
288+
289+ if (visibilityChangeListener != null ) {
290+ if (GONE == visibility ) {
291+ visibilityChangeListener .onAlertDismissCompletion (this );
292+ }
293+ else if (VISIBLE == visibility ) {
294+ visibilityChangeListener .onAlertAppearCompletion (this );
295+ }
296+ }
297+ }
298+
299+ // Animation change listener
300+
301+ @ Override
302+ public void onAnimationStart (Animation animation ) {
303+
304+ }
305+
306+ @ Override
307+ public void onAnimationEnd (Animation animation ) {
308+
309+ if (animation == fadeInAnimation ) {
310+ setVisibility (VISIBLE );
311+ }
312+ else if (animation == fadeOutAnimation ) {
313+ setVisibility (GONE );
314+ }
315+ else {
316+ throw new IllegalStateException ("Unsupported animation attempted to use this listener" );
317+ }
318+ }
319+
320+ @ Override
321+ public void onAnimationRepeat (Animation animation ) {
322+
232323 }
233324}
0 commit comments