2013-04-24 05:48:29 +00:00
|
|
|
/**
|
|
|
|
* 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 com.android.inputmethod.dictionarypack;
|
|
|
|
|
2013-04-24 06:27:56 +00:00
|
|
|
import android.animation.Animator;
|
|
|
|
import android.animation.AnimatorListenerAdapter;
|
2013-04-24 05:48:29 +00:00
|
|
|
import android.content.Context;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.view.View;
|
2013-04-24 06:27:56 +00:00
|
|
|
import android.view.ViewPropertyAnimator;
|
2013-04-24 05:48:29 +00:00
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
|
|
|
|
import com.android.inputmethod.latin.R;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A view that handles buttons inside it according to a status.
|
|
|
|
*/
|
|
|
|
public class ButtonSwitcher extends FrameLayout {
|
2013-04-24 05:55:21 +00:00
|
|
|
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;
|
|
|
|
|
2013-04-24 05:48:29 +00:00
|
|
|
// Animation directions
|
|
|
|
public static final int ANIMATION_IN = 1;
|
|
|
|
public static final int ANIMATION_OUT = 2;
|
|
|
|
|
2013-04-24 05:55:21 +00:00
|
|
|
private Button mInstallButton;
|
|
|
|
private Button mCancelButton;
|
|
|
|
private Button mDeleteButton;
|
2013-07-08 09:46:33 +00:00
|
|
|
private DictionaryListInterfaceState mInterfaceState;
|
2013-04-24 05:55:21 +00:00
|
|
|
private OnClickListener mOnClickListener;
|
|
|
|
|
2013-04-24 05:48:29 +00:00
|
|
|
public ButtonSwitcher(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ButtonSwitcher(Context context, AttributeSet attrs, int defStyle) {
|
|
|
|
super(context, attrs, defStyle);
|
|
|
|
}
|
|
|
|
|
2013-07-08 09:46:33 +00:00
|
|
|
public void reset(final DictionaryListInterfaceState interfaceState) {
|
2013-05-28 11:28:52 +00:00
|
|
|
mStatus = NOT_INITIALIZED;
|
|
|
|
mAnimateToStatus = NOT_INITIALIZED;
|
2013-07-08 09:46:33 +00:00
|
|
|
mInterfaceState = interfaceState;
|
2013-05-28 11:28:52 +00:00
|
|
|
}
|
|
|
|
|
2013-04-24 05:55:21 +00:00
|
|
|
@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);
|
2013-05-28 11:28:52 +00:00
|
|
|
setInternalOnClickListener(mOnClickListener);
|
2013-04-24 05:55:21 +00:00
|
|
|
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;
|
|
|
|
}
|
2013-04-24 05:48:29 +00:00
|
|
|
}
|
|
|
|
|
2013-04-24 05:55:21 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void animateButtonPosition(final int oldStatus, final int newStatus) {
|
2013-04-24 06:27:56 +00:00
|
|
|
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) {
|
2013-04-24 09:21:44 +00:00
|
|
|
if (newStatus != mStatus) return;
|
2013-04-24 06:27:56 +00:00
|
|
|
animateButton(newButton, ANIMATION_IN);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else if (null != oldButton) {
|
|
|
|
animateButton(oldButton, ANIMATION_OUT);
|
|
|
|
} else if (null != newButton) {
|
|
|
|
animateButton(newButton, ANIMATION_IN);
|
|
|
|
}
|
2013-04-24 05:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setInternalOnClickListener(final OnClickListener listener) {
|
2013-04-24 05:55:21 +00:00
|
|
|
mOnClickListener = listener;
|
2013-05-28 11:28:52 +00:00
|
|
|
if (null != mInstallButton) {
|
|
|
|
// Already laid out : do it now
|
|
|
|
mInstallButton.setOnClickListener(mOnClickListener);
|
|
|
|
mCancelButton.setOnClickListener(mOnClickListener);
|
|
|
|
mDeleteButton.setOnClickListener(mOnClickListener);
|
|
|
|
}
|
2013-04-24 05:48:29 +00:00
|
|
|
}
|
|
|
|
|
2013-04-24 06:27:56 +00:00
|
|
|
private ViewPropertyAnimator animateButton(final View button, final int direction) {
|
2013-04-24 05:48:29 +00:00
|
|
|
final float outerX = getWidth();
|
|
|
|
final float innerX = button.getX() - button.getTranslationX();
|
2013-07-08 09:46:33 +00:00
|
|
|
mInterfaceState.removeFromCache((View)getParent());
|
2013-04-24 05:48:29 +00:00
|
|
|
if (ANIMATION_IN == direction) {
|
2013-04-24 09:21:44 +00:00
|
|
|
button.setClickable(true);
|
2013-04-24 06:27:56 +00:00
|
|
|
return button.animate().translationX(0);
|
2013-04-24 05:48:29 +00:00
|
|
|
} else {
|
2013-04-24 09:21:44 +00:00
|
|
|
button.setClickable(false);
|
2013-04-24 06:27:56 +00:00
|
|
|
return button.animate().translationX(outerX - innerX);
|
2013-04-24 05:48:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|