mobile/android/base/widget/ButtonToast.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * Copyright 2012 Roman Nurik
     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  */
    17 package org.mozilla.gecko.widget;
    19 import java.util.LinkedList;
    21 import org.mozilla.gecko.R;
    22 import org.mozilla.gecko.animation.PropertyAnimator;
    24 import android.graphics.drawable.Drawable;
    25 import android.os.Bundle;
    26 import android.os.Handler;
    27 import android.view.View;
    28 import android.widget.Button;
    29 import android.widget.TextView;
    31 public class ButtonToast {
    32     private final static String LOGTAG = "GeckoButtonToast";
    33     private final static int TOAST_DURATION = 5000;
    35     private final View mView;
    36     private final TextView mMessageView;
    37     private final Button mButton;
    38     private final Handler mHideHandler = new Handler();
    40     private final ToastListener mListener;
    41     private final LinkedList<Toast> mQueue = new LinkedList<Toast>();
    42     private Toast mCurrentToast;
    44     public enum ReasonHidden {
    45         CLICKED,
    46         TIMEOUT,
    47         STARTUP
    48     }
    50     // State objects
    51     private static class Toast {
    52         public final CharSequence buttonMessage;
    53         public Drawable buttonDrawable;
    54         public final CharSequence message;
    55         public ToastListener listener;
    57         public Toast(CharSequence aMessage, CharSequence aButtonMessage,
    58                      Drawable aDrawable, ToastListener aListener) {
    59             message = aMessage;
    60             buttonMessage = aButtonMessage;
    61             buttonDrawable = aDrawable;
    62             listener = aListener;
    63         }
    64     }
    66     public interface ToastListener {
    67         void onButtonClicked();
    68         void onToastHidden(ReasonHidden reason);
    69     }
    71     public ButtonToast(View view) {
    72         mView = view;
    73         mListener = null;
    74         mMessageView = (TextView) mView.findViewById(R.id.toast_message);
    75         mButton = (Button) mView.findViewById(R.id.toast_button);
    76         mButton.setOnClickListener(new View.OnClickListener() {
    77                     @Override
    78                     public void onClick(View view) {
    79                         Toast t = mCurrentToast;
    80                         if (t == null)
    81                             return;
    83                         hide(false, ReasonHidden.CLICKED);
    84                         if (t.listener != null) {
    85                             t.listener.onButtonClicked();
    86                         }
    87                     }
    88                 });
    90         hide(true, ReasonHidden.STARTUP);
    91     }
    93     public void show(boolean immediate, CharSequence message,
    94                      CharSequence buttonMessage, Drawable buttonDrawable,
    95                      ToastListener listener) {
    96         show(new Toast(message, buttonMessage, buttonDrawable, listener), immediate);
    97     }
    99     private void show(Toast t, boolean immediate) {
   100         // If we're already showing a toast, add this one to the queue to show later
   101         if (mView.getVisibility() == View.VISIBLE) {
   102             mQueue.offer(t);
   103             return;
   104         }
   106         mCurrentToast = t;
   107         mButton.setEnabled(true);
   109         mMessageView.setText(t.message);
   110         mButton.setText(t.buttonMessage);
   111         mButton.setCompoundDrawablePadding(mView.getContext().getResources().getDimensionPixelSize(R.dimen.toast_button_padding));
   112         mButton.setCompoundDrawablesWithIntrinsicBounds(t.buttonDrawable, null, null, null);
   114         mHideHandler.removeCallbacks(mHideRunnable);
   115         mHideHandler.postDelayed(mHideRunnable, TOAST_DURATION);
   117         mView.setVisibility(View.VISIBLE);
   118         int duration = immediate ? 0 : mView.getResources().getInteger(android.R.integer.config_longAnimTime);
   120         PropertyAnimator animator = new PropertyAnimator(duration);
   121         animator.attach(mView, PropertyAnimator.Property.ALPHA, 1.0f);
   122         animator.start();
   123     }
   125     public void hide(boolean immediate, ReasonHidden reason) {
   126         if (mButton.isPressed() && reason != ReasonHidden.CLICKED) {
   127             mHideHandler.postDelayed(mHideRunnable, TOAST_DURATION);
   128             return;
   129         }
   131         if (mCurrentToast != null && mCurrentToast.listener != null) {
   132             mCurrentToast.listener.onToastHidden(reason);
   133         }
   134         mCurrentToast = null;
   135         mButton.setEnabled(false);
   136         mHideHandler.removeCallbacks(mHideRunnable);
   137         int duration = immediate ? 0 : mView.getResources().getInteger(android.R.integer.config_longAnimTime);
   139         mView.clearAnimation();
   140         if (immediate) {
   141             mView.setVisibility(View.GONE);
   142             showNextInQueue();
   143         } else {
   144             // Using Android's animation frameworks will not correctly turn off clicking.
   145             // See bug 885717.
   146             PropertyAnimator animator = new PropertyAnimator(duration);
   147             animator.attach(mView, PropertyAnimator.Property.ALPHA, 0.0f);
   148             animator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener () {
   149                 // If we are showing a toast and go in the background
   150                 // onAnimationEnd will be called when the app is restored
   151                 public void onPropertyAnimationEnd() {
   152                     mView.setVisibility(View.GONE);
   153                     showNextInQueue();
   154                 }
   155                 public void onPropertyAnimationStart() { }
   156             });
   157             animator.start();
   158         }
   159     }
   161     public void onSaveInstanceState(Bundle outState) {
   162         // Add whatever toast we're currently showing to the front of the queue
   163         if (mCurrentToast != null) {
   164             mQueue.add(0, mCurrentToast);
   165         }
   166     }
   168     private void showNextInQueue() {
   169         Toast t = mQueue.poll();
   170         if (t != null) {
   171             show(t, false);
   172         }
   173     }
   175     private Runnable mHideRunnable = new Runnable() {
   176         @Override
   177         public void run() {
   178             hide(false, ReasonHidden.TIMEOUT);
   179         }
   180     };
   181 }

mercurial