aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java')
-rw-r--r--java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java170
1 files changed, 170 insertions, 0 deletions
diff --git a/java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java b/java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java
new file mode 100644
index 000000000..46692559e
--- /dev/null
+++ b/java/src/org/kelar/inputmethod/dictionarypack/ButtonSwitcher.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kelar.inputmethod.dictionarypack;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.widget.Button;
+import android.widget.FrameLayout;
+
+import org.kelar.inputmethod.latin.R;
+
+/**
+ * A view that handles buttons inside it according to a status.
+ */
+public class ButtonSwitcher extends FrameLayout {
+ public static final int NOT_INITIALIZED = -1;
+ public static final int STATUS_NO_BUTTON = 0;
+ public static final int STATUS_INSTALL = 1;
+ public static final int STATUS_CANCEL = 2;
+ public static final int STATUS_DELETE = 3;
+ // One of the above
+ private int mStatus = NOT_INITIALIZED;
+ private int mAnimateToStatus = NOT_INITIALIZED;
+
+ // Animation directions
+ public static final int ANIMATION_IN = 1;
+ public static final int ANIMATION_OUT = 2;
+
+ private Button mInstallButton;
+ private Button mCancelButton;
+ private Button mDeleteButton;
+ private DictionaryListInterfaceState mInterfaceState;
+ private OnClickListener mOnClickListener;
+
+ public ButtonSwitcher(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ButtonSwitcher(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void reset(final DictionaryListInterfaceState interfaceState) {
+ mStatus = NOT_INITIALIZED;
+ mAnimateToStatus = NOT_INITIALIZED;
+ mInterfaceState = interfaceState;
+ }
+
+ @Override
+ protected void onLayout(final boolean changed, final int left, final int top, final int right,
+ final int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mInstallButton = (Button)findViewById(R.id.dict_install_button);
+ mCancelButton = (Button)findViewById(R.id.dict_cancel_button);
+ mDeleteButton = (Button)findViewById(R.id.dict_delete_button);
+ setInternalOnClickListener(mOnClickListener);
+ setButtonPositionWithoutAnimation(mStatus);
+ if (mAnimateToStatus != NOT_INITIALIZED) {
+ // We have been asked to animate before we were ready, so we took a note of it.
+ // We are now ready: launch the animation.
+ animateButtonPosition(mStatus, mAnimateToStatus);
+ mStatus = mAnimateToStatus;
+ mAnimateToStatus = NOT_INITIALIZED;
+ }
+ }
+
+ private Button getButton(final int status) {
+ switch(status) {
+ case STATUS_INSTALL:
+ return mInstallButton;
+ case STATUS_CANCEL:
+ return mCancelButton;
+ case STATUS_DELETE:
+ return mDeleteButton;
+ default:
+ return null;
+ }
+ }
+
+ public void setStatusAndUpdateVisuals(final int status) {
+ if (mStatus == NOT_INITIALIZED) {
+ setButtonPositionWithoutAnimation(status);
+ mStatus = status;
+ } else {
+ if (null == mInstallButton) {
+ // We may come here before we have been layout. In this case we don't know our
+ // size yet so we can't start animations so we need to remember what animation to
+ // start once layout has gone through.
+ mAnimateToStatus = status;
+ } else {
+ animateButtonPosition(mStatus, status);
+ mStatus = status;
+ }
+ }
+ }
+
+ private void setButtonPositionWithoutAnimation(final int status) {
+ // This may be called by setStatus() before the layout has come yet.
+ if (null == mInstallButton) return;
+ final int width = getWidth();
+ // Set to out of the screen if that's not the currently displayed status
+ mInstallButton.setTranslationX(STATUS_INSTALL == status ? 0 : width);
+ mCancelButton.setTranslationX(STATUS_CANCEL == status ? 0 : width);
+ mDeleteButton.setTranslationX(STATUS_DELETE == status ? 0 : width);
+ }
+
+ // The helper method for {@link AnimatorListenerAdapter}.
+ void animateButtonIfStatusIsEqual(final View newButton, final int newStatus) {
+ if (newStatus != mStatus) return;
+ animateButton(newButton, ANIMATION_IN);
+ }
+
+ private void animateButtonPosition(final int oldStatus, final int newStatus) {
+ final View oldButton = getButton(oldStatus);
+ final View newButton = getButton(newStatus);
+ if (null != oldButton && null != newButton) {
+ // Transition between two buttons : animate out, then in
+ animateButton(oldButton, ANIMATION_OUT).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ animateButtonIfStatusIsEqual(newButton, newStatus);
+ }
+ });
+ } else if (null != oldButton) {
+ animateButton(oldButton, ANIMATION_OUT);
+ } else if (null != newButton) {
+ animateButton(newButton, ANIMATION_IN);
+ }
+ }
+
+ public void setInternalOnClickListener(final OnClickListener listener) {
+ mOnClickListener = listener;
+ if (null != mInstallButton) {
+ // Already laid out : do it now
+ mInstallButton.setOnClickListener(mOnClickListener);
+ mCancelButton.setOnClickListener(mOnClickListener);
+ mDeleteButton.setOnClickListener(mOnClickListener);
+ }
+ }
+
+ private ViewPropertyAnimator animateButton(final View button, final int direction) {
+ final float outerX = getWidth();
+ final float innerX = button.getX() - button.getTranslationX();
+ mInterfaceState.removeFromCache((View)getParent());
+ if (ANIMATION_IN == direction) {
+ button.setClickable(true);
+ return button.animate().translationX(0);
+ }
+ button.setClickable(false);
+ return button.animate().translationX(outerX - innerX);
+ }
+}