• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */
16 
17 package com.android.inputmethod.dictionarypack;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorListenerAdapter;
21 import android.content.Context;
22 import android.util.AttributeSet;
23 import android.view.View;
24 import android.view.ViewPropertyAnimator;
25 import android.widget.Button;
26 import android.widget.FrameLayout;
27 
28 import com.android.inputmethod.latin.R;
29 
30 /**
31  * A view that handles buttons inside it according to a status.
32  */
33 public class ButtonSwitcher extends FrameLayout {
34     public static final int NOT_INITIALIZED = -1;
35     public static final int STATUS_NO_BUTTON = 0;
36     public static final int STATUS_INSTALL = 1;
37     public static final int STATUS_CANCEL = 2;
38     public static final int STATUS_DELETE = 3;
39     // One of the above
40     private int mStatus = NOT_INITIALIZED;
41     private int mAnimateToStatus = NOT_INITIALIZED;
42 
43     // Animation directions
44     public static final int ANIMATION_IN = 1;
45     public static final int ANIMATION_OUT = 2;
46 
47     private Button mInstallButton;
48     private Button mCancelButton;
49     private Button mDeleteButton;
50     private OnClickListener mOnClickListener;
51 
ButtonSwitcher(Context context, AttributeSet attrs)52     public ButtonSwitcher(Context context, AttributeSet attrs) {
53         super(context, attrs);
54     }
55 
ButtonSwitcher(Context context, AttributeSet attrs, int defStyle)56     public ButtonSwitcher(Context context, AttributeSet attrs, int defStyle) {
57         super(context, attrs, defStyle);
58     }
59 
60     @Override
onLayout(final boolean changed, final int left, final int top, final int right, final int bottom)61     protected void onLayout(final boolean changed, final int left, final int top, final int right,
62             final int bottom) {
63         super.onLayout(changed, left, top, right, bottom);
64         mInstallButton = (Button)findViewById(R.id.dict_install_button);
65         mCancelButton = (Button)findViewById(R.id.dict_cancel_button);
66         mDeleteButton = (Button)findViewById(R.id.dict_delete_button);
67         mInstallButton.setOnClickListener(mOnClickListener);
68         mCancelButton.setOnClickListener(mOnClickListener);
69         mDeleteButton.setOnClickListener(mOnClickListener);
70         setButtonPositionWithoutAnimation(mStatus);
71         if (mAnimateToStatus != NOT_INITIALIZED) {
72             // We have been asked to animate before we were ready, so we took a note of it.
73             // We are now ready: launch the animation.
74             animateButtonPosition(mStatus, mAnimateToStatus);
75             mStatus = mAnimateToStatus;
76             mAnimateToStatus = NOT_INITIALIZED;
77         }
78     }
79 
getButton(final int status)80     private Button getButton(final int status) {
81         switch(status) {
82         case STATUS_INSTALL:
83             return mInstallButton;
84         case STATUS_CANCEL:
85             return mCancelButton;
86         case STATUS_DELETE:
87             return mDeleteButton;
88         default:
89             return null;
90         }
91     }
92 
setStatusAndUpdateVisuals(final int status)93     public void setStatusAndUpdateVisuals(final int status) {
94         if (mStatus == NOT_INITIALIZED) {
95             setButtonPositionWithoutAnimation(status);
96             mStatus = status;
97         } else {
98             if (null == mInstallButton) {
99                 // We may come here before we have been layout. In this case we don't know our
100                 // size yet so we can't start animations so we need to remember what animation to
101                 // start once layout has gone through.
102                 mAnimateToStatus = status;
103             } else {
104                 animateButtonPosition(mStatus, status);
105                 mStatus = status;
106             }
107         }
108     }
109 
setButtonPositionWithoutAnimation(final int status)110     private void setButtonPositionWithoutAnimation(final int status) {
111         // This may be called by setStatus() before the layout has come yet.
112         if (null == mInstallButton) return;
113         final int width = getWidth();
114         // Set to out of the screen if that's not the currently displayed status
115         mInstallButton.setTranslationX(STATUS_INSTALL == status ? 0 : width);
116         mCancelButton.setTranslationX(STATUS_CANCEL == status ? 0 : width);
117         mDeleteButton.setTranslationX(STATUS_DELETE == status ? 0 : width);
118     }
119 
animateButtonPosition(final int oldStatus, final int newStatus)120     private void animateButtonPosition(final int oldStatus, final int newStatus) {
121         final View oldButton = getButton(oldStatus);
122         final View newButton = getButton(newStatus);
123         if (null != oldButton && null != newButton) {
124             // Transition between two buttons : animate out, then in
125             animateButton(oldButton, ANIMATION_OUT).setListener(
126                     new AnimatorListenerAdapter() {
127                         @Override
128                         public void onAnimationEnd(final Animator animation) {
129                             if (newStatus != mStatus) return;
130                             animateButton(newButton, ANIMATION_IN);
131                         }
132                     });
133         } else if (null != oldButton) {
134             animateButton(oldButton, ANIMATION_OUT);
135         } else if (null != newButton) {
136             animateButton(newButton, ANIMATION_IN);
137         }
138     }
139 
setInternalOnClickListener(final OnClickListener listener)140     public void setInternalOnClickListener(final OnClickListener listener) {
141         mOnClickListener = listener;
142     }
143 
animateButton(final View button, final int direction)144     private ViewPropertyAnimator animateButton(final View button, final int direction) {
145         final float outerX = getWidth();
146         final float innerX = button.getX() - button.getTranslationX();
147         if (ANIMATION_IN == direction) {
148             button.setClickable(true);
149             return button.animate().translationX(0);
150         } else {
151             button.setClickable(false);
152             return button.animate().translationX(outerX - innerX);
153         }
154     }
155 }
156