diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/anim/key_preview_fadein.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9fad7b9a748fc07864b07d7bfdad120856bac116
--- /dev/null
+++ b/java/res/anim/key_preview_fadein.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/decelerate_interpolator"
+>
+    <alpha
+        android:fromAlpha="0.5"
+        android:toAlpha="1.0"
+        android:duration="@integer/config_preview_fadein_anim_time" />
+</set>
diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/anim/key_preview_fadeout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7de5123cd458ea582da087a0f023b147847b1d84
--- /dev/null
+++ b/java/res/anim/key_preview_fadeout.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+>
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:duration="@integer/config_preview_fadeout_anim_time" />
+</set>
diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/mini_keyboard_fadein.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9fad7b9a748fc07864b07d7bfdad120856bac116
--- /dev/null
+++ b/java/res/anim/mini_keyboard_fadein.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/decelerate_interpolator"
+>
+    <alpha
+        android:fromAlpha="0.5"
+        android:toAlpha="1.0"
+        android:duration="@integer/config_preview_fadein_anim_time" />
+</set>
diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/mini_keyboard_fadeout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7de5123cd458ea582da087a0f023b147847b1d84
--- /dev/null
+++ b/java/res/anim/mini_keyboard_fadeout.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/accelerate_interpolator"
+>
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:duration="@integer/config_preview_fadeout_anim_time" />
+</set>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6e941baaf099618546d0d50b2b819584c51fc369
--- /dev/null
+++ b/java/res/values/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<resources>
+    <integer name="config_delay_before_preview">0</integer>
+    <integer name="config_delay_after_preview">10</integer>
+    <integer name="config_preview_fadein_anim_time">0</integer>
+    <integer name="config_preview_fadeout_anim_time">90</integer>
+    <integer name="config_mini_keyboard_fadein_anim_time">0</integer>
+    <integer name="config_mini_keyboard_fadeout_anim_time">100</integer>
+</resources>
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 60fffe8738f4ac33d981729f9932be327292f569..5e239482f22221bccd455b5d8c77b84d5f5039ef 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -33,4 +33,12 @@
         <item name="backgroundDimAmount">0.5</item>
         <item name="symbolColorScheme">white</item>
     </style>
+    <style name="KeyPreviewAnimation">
+        <item name="android:windowEnterAnimation">@anim/key_preview_fadein</item>
+        <item name="android:windowExitAnimation">@anim/key_preview_fadeout</item>
+    </style>
+    <style name="MiniKeyboardAnimation">
+        <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
+        <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item>
+    </style>
 </resources>
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index eeccb965cf52ff3897b1e363ecb9e875e50d1dfb..3761dab14602cda26e9d1af86fbcace7178f81cd 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -154,8 +154,6 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
     }
 
     // Timing constants
-    private static final int DELAY_BEFORE_PREVIEW = 0;
-    private static final int DELAY_AFTER_PREVIEW = 100;
     private static final int REPEAT_INTERVAL = PointerTracker.REPEAT_INTERVAL;
 
     // Miscellaneous constants
@@ -194,6 +192,8 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
     private int mPopupPreviewOffsetY;
     private int mWindowY;
     private int mPopupPreviewDisplayedY;
+    private final int mDelayBeforePreview;
+    private final int mDelayAfterPreview;
 
     // Popup mini keyboard
     private PopupWindow mMiniKeyboardPopup;
@@ -255,7 +255,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
                     showKey(msg.arg1, (PointerTracker)msg.obj);
                     break;
                 case MSG_DISMISS_PREVIEW:
-                    mPreviewText.setVisibility(INVISIBLE);
+                    mPreviewPopup.dismiss();
                     break;
                 case MSG_REPEAT_KEY: {
                     final PointerTracker tracker = (PointerTracker)msg.obj;
@@ -460,6 +460,8 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
             }
         }
 
+        final Resources res = getResources();
+
         mPreviewPopup = new PopupWindow(context);
         if (previewLayout != 0) {
             mPreviewText = (TextView) inflate.inflate(previewLayout, null);
@@ -470,10 +472,14 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
             mShowPreview = false;
         }
         mPreviewPopup.setTouchable(false);
-        mMiniKeyboardParent = this;
+        mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
+        mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
+        mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
 
+        mMiniKeyboardParent = this;
         mMiniKeyboardPopup = new PopupWindow(context);
         mMiniKeyboardPopup.setBackgroundDrawable(null);
+        mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation);
 
         mPaint = new Paint();
         mPaint.setAntiAlias(true);
@@ -485,7 +491,6 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
         mMiniKeyboardCache = new HashMap<Key,View>();
         mKeyBackground.getPadding(mPadding);
 
-        final Resources res = getResources();
         mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);
         // TODO: Refer frameworks/base/core/res/res/values/config.xml
         mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation);
@@ -657,9 +662,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
     public void setPopupOffset(int x, int y) {
         mPopupPreviewOffsetX = x;
         mPopupPreviewOffsetY = y;
-        if (mPreviewPopup.isShowing()) {
-            mPreviewPopup.dismiss();
-        }
+        mPreviewPopup.dismiss();
     }
 
     /**
@@ -895,9 +898,9 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
                         || (hidePreviewOrShowSpaceKeyPreview && isLanguageSwitchEnabled))) {
             if (keyIndex == NOT_A_KEY) {
                 mHandler.cancelPopupPreview();
-                mHandler.dismissPreview(DELAY_AFTER_PREVIEW);
+                mHandler.dismissPreview(mDelayAfterPreview);
             } else if (tracker != null) {
-                mHandler.popupPreview(DELAY_BEFORE_PREVIEW, keyIndex, tracker);
+                mHandler.popupPreview(mDelayBeforePreview, keyIndex, tracker);
             }
         }
     }
@@ -1375,9 +1378,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
     }
 
     public void closing() {
-        if (mPreviewPopup.isShowing()) {
-            mPreviewPopup.dismiss();
-        }
+        mPreviewPopup.dismiss();
         mHandler.cancelAllMessages();
 
         dismissPopupKeyboard();