am 13a2e1b2: am 4dc77dcf: Merge "[PB7] Export animation code out of the preference"
* commit '13a2e1b245c56812fd91099b4fe91a6111a14c0f': [PB7] Export animation code out of the preferencemain
commit
b7853edee0
|
@ -84,5 +84,21 @@
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:text="@string/install_dict" />
|
android:text="@string/install_dict" />
|
||||||
|
<Button
|
||||||
|
android:id="@+android:id/dict_cancel_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right|center_vertical"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/cancel_download_dict" />
|
||||||
|
<Button
|
||||||
|
android:id="@+android:id/dict_delete_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right|center_vertical"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/delete_dict" />
|
||||||
</com.android.inputmethod.dictionarypack.ButtonSwitcher>
|
</com.android.inputmethod.dictionarypack.ButtonSwitcher>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -28,10 +28,24 @@ import com.android.inputmethod.latin.R;
|
||||||
* A view that handles buttons inside it according to a status.
|
* A view that handles buttons inside it according to a status.
|
||||||
*/
|
*/
|
||||||
public class ButtonSwitcher extends FrameLayout {
|
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
|
// Animation directions
|
||||||
public static final int ANIMATION_IN = 1;
|
public static final int ANIMATION_IN = 1;
|
||||||
public static final int ANIMATION_OUT = 2;
|
public static final int ANIMATION_OUT = 2;
|
||||||
|
|
||||||
|
private Button mInstallButton;
|
||||||
|
private Button mCancelButton;
|
||||||
|
private Button mDeleteButton;
|
||||||
|
private OnClickListener mOnClickListener;
|
||||||
|
|
||||||
public ButtonSwitcher(Context context, AttributeSet attrs) {
|
public ButtonSwitcher(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
@ -40,26 +54,79 @@ public class ButtonSwitcher extends FrameLayout {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(final CharSequence text) {
|
@Override
|
||||||
((Button)findViewById(R.id.dict_install_button)).setText(text);
|
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);
|
||||||
|
mInstallButton.setOnClickListener(mOnClickListener);
|
||||||
|
mCancelButton.setOnClickListener(mOnClickListener);
|
||||||
|
mDeleteButton.setOnClickListener(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInternalButtonVisiblility(final int visibility) {
|
private Button getButton(final int status) {
|
||||||
findViewById(R.id.dict_install_button).setVisibility(visibility);
|
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) {
|
||||||
|
animateButton(getButton(oldStatus), ANIMATION_OUT);
|
||||||
|
animateButton(getButton(newStatus), ANIMATION_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInternalOnClickListener(final OnClickListener listener) {
|
public void setInternalOnClickListener(final OnClickListener listener) {
|
||||||
findViewById(R.id.dict_install_button).setOnClickListener(listener);
|
mOnClickListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void animateButton(final int direction) {
|
private void animateButton(final View button, final int direction) {
|
||||||
final View button = findViewById(R.id.dict_install_button);
|
if (null == button) return;
|
||||||
final float outerX = getWidth();
|
final float outerX = getWidth();
|
||||||
final float innerX = button.getX() - button.getTranslationX();
|
final float innerX = button.getX() - button.getTranslationX();
|
||||||
if (View.INVISIBLE == button.getVisibility()) {
|
|
||||||
button.setTranslationX(outerX - innerX);
|
|
||||||
button.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
if (ANIMATION_IN == direction) {
|
if (ANIMATION_IN == direction) {
|
||||||
button.animate().translationX(0);
|
button.animate().translationX(0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -110,29 +110,31 @@ public final class WordListPreference extends Preference {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The table below needs to be kept in sync with MetadataDbHelper.STATUS_* since it uses
|
||||||
|
// the values as indices.
|
||||||
private static final int sStatusActionList[][] = {
|
private static final int sStatusActionList[][] = {
|
||||||
// MetadataDbHelper.STATUS_UNKNOWN
|
// MetadataDbHelper.STATUS_UNKNOWN
|
||||||
{},
|
{},
|
||||||
// MetadataDbHelper.STATUS_AVAILABLE
|
// MetadataDbHelper.STATUS_AVAILABLE
|
||||||
{ R.string.install_dict, ACTION_ENABLE_DICT },
|
{ ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT },
|
||||||
// MetadataDbHelper.STATUS_DOWNLOADING
|
// MetadataDbHelper.STATUS_DOWNLOADING
|
||||||
{ R.string.cancel_download_dict, ACTION_DISABLE_DICT },
|
{ ButtonSwitcher.STATUS_CANCEL, ACTION_DISABLE_DICT },
|
||||||
// MetadataDbHelper.STATUS_INSTALLED
|
// MetadataDbHelper.STATUS_INSTALLED
|
||||||
{ R.string.delete_dict, ACTION_DELETE_DICT },
|
{ ButtonSwitcher.STATUS_DELETE, ACTION_DELETE_DICT },
|
||||||
// MetadataDbHelper.STATUS_DISABLED
|
// MetadataDbHelper.STATUS_DISABLED
|
||||||
{ R.string.delete_dict, ACTION_DELETE_DICT },
|
{ ButtonSwitcher.STATUS_DELETE, ACTION_DELETE_DICT },
|
||||||
// MetadataDbHelper.STATUS_DELETING
|
// MetadataDbHelper.STATUS_DELETING
|
||||||
// We show 'install' because the file is supposed to be deleted.
|
// We show 'install' because the file is supposed to be deleted.
|
||||||
// The user may reinstall it.
|
// The user may reinstall it.
|
||||||
{ R.string.install_dict, ACTION_ENABLE_DICT }
|
{ ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT }
|
||||||
};
|
};
|
||||||
|
|
||||||
private CharSequence getButtonLabel(final int status) {
|
private int getButtonSwitcherStatus(final int status) {
|
||||||
if (status >= sStatusActionList.length) {
|
if (status >= sStatusActionList.length) {
|
||||||
Log.e(TAG, "Unknown status " + status);
|
Log.e(TAG, "Unknown status " + status);
|
||||||
return "";
|
return ButtonSwitcher.STATUS_NO_BUTTON;
|
||||||
}
|
}
|
||||||
return mContext.getString(sStatusActionList[status][0]);
|
return sStatusActionList[status][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getActionIdFromStatusAndMenuEntry(final int status) {
|
private static int getActionIdFromStatusAndMenuEntry(final int status) {
|
||||||
|
@ -189,9 +191,8 @@ public final class WordListPreference extends Preference {
|
||||||
((ViewGroup)view).setLayoutTransition(null);
|
((ViewGroup)view).setLayoutTransition(null);
|
||||||
final ButtonSwitcher buttonSwitcher =
|
final ButtonSwitcher buttonSwitcher =
|
||||||
(ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher);
|
(ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher);
|
||||||
buttonSwitcher.setText(getButtonLabel(mStatus));
|
buttonSwitcher.setStatusAndUpdateVisuals(mInterfaceState.isOpen(mWordlistId) ?
|
||||||
buttonSwitcher.setInternalButtonVisiblility(mInterfaceState.isOpen(mWordlistId) ?
|
getButtonSwitcherStatus(mStatus) : ButtonSwitcher.STATUS_NO_BUTTON);
|
||||||
View.VISIBLE : View.INVISIBLE);
|
|
||||||
buttonSwitcher.setInternalOnClickListener(mActionButtonClickHandler);
|
buttonSwitcher.setInternalOnClickListener(mActionButtonClickHandler);
|
||||||
view.setOnClickListener(mPreferenceClickHandler);
|
view.setOnClickListener(mPreferenceClickHandler);
|
||||||
}
|
}
|
||||||
|
@ -224,9 +225,9 @@ public final class WordListPreference extends Preference {
|
||||||
final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i)
|
final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i)
|
||||||
.findViewById(R.id.wordlist_button_switcher);
|
.findViewById(R.id.wordlist_button_switcher);
|
||||||
if (i == indexToOpen) {
|
if (i == indexToOpen) {
|
||||||
buttonSwitcher.animateButton(ButtonSwitcher.ANIMATION_IN);
|
buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(mStatus));
|
||||||
} else {
|
} else {
|
||||||
buttonSwitcher.animateButton(ButtonSwitcher.ANIMATION_OUT);
|
buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue