Word suggestion popup added to EditText.
A double tap on a word will now display a list of suggestions based
on the CorrectionSpans that were added by the IME.
This is a first implementation of this feature. It needs some attention from
designers.
Change-Id: If863107681ce82a1639f21315878f830c2991fb7
diff --git a/api/current.xml b/api/current.xml
index 58aa1fd..2ee325b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -10025,6 +10025,39 @@
visibility="public"
>
</field>
+<field name="textEditSuggestionItemLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843626"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textEditSuggestionsBottomWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843624"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textEditSuggestionsTopWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843625"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textFilterEnabled"
type="int"
transient="false"
@@ -10146,6 +10179,17 @@
visibility="public"
>
</field>
+<field name="textSuggestionsWindowStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843623"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textViewStyle"
type="int"
transient="false"
@@ -267716,7 +267760,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9e482b4..f5de16f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -43,7 +43,6 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
@@ -88,6 +87,7 @@
import android.text.style.UpdateAppearance;
import android.text.util.Linkify;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.util.Log;
import android.util.TypedValue;
@@ -311,6 +311,10 @@
private int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
private int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
+ private int mTextEditSuggestionsBottomWindowLayout, mTextEditSuggestionsTopWindowLayout;
+ private int mTextEditSuggestionItemLayout;
+ private SuggestionsPopupWindow mSuggestionsPopupWindow;
+
private int mCursorDrawableRes;
private final Drawable[] mCursorDrawable = new Drawable[2];
private int mCursorCount; // Actual current number of used mCursorDrawable: 0, 1 or 2
@@ -779,6 +783,18 @@
mTextEditSideNoPasteWindowLayout = a.getResourceId(attr, 0);
break;
+ case com.android.internal.R.styleable.TextView_textEditSuggestionsBottomWindowLayout:
+ mTextEditSuggestionsBottomWindowLayout = a.getResourceId(attr, 0);
+ break;
+
+ case com.android.internal.R.styleable.TextView_textEditSuggestionsTopWindowLayout:
+ mTextEditSuggestionsTopWindowLayout = a.getResourceId(attr, 0);
+ break;
+
+ case com.android.internal.R.styleable.TextView_textEditSuggestionItemLayout:
+ mTextEditSuggestionItemLayout = a.getResourceId(attr, 0);
+ break;
+
case com.android.internal.R.styleable.TextView_textIsSelectable:
mTextIsSelectable = a.getBoolean(attr, false);
break;
@@ -7351,6 +7367,7 @@
startSelectionActionMode();
} else {
stopSelectionActionMode();
+ hideSuggestions();
if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
getInsertionController().show();
}
@@ -7784,7 +7801,7 @@
// Cases where the text ends with a '.' and we select from the end of the line
// (right after the dot), or when we select from the space character in "aaa, bbb".
continue;
- }
+ }
if (type == Character.SURROGATE) { // Two Character codepoint
end = start - 1; // Recheck as a pair when scanning forward
continue;
@@ -8229,6 +8246,201 @@
return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
}
+ private class SuggestionsPopupWindow implements OnClickListener {
+ private static final int MAX_NUMBER_SUGGESTIONS = 5;
+ private static final long NO_SUGGESTIONS = -1L;
+ private final PopupWindow mContainer;
+ private final ViewGroup[] mSuggestionViews = new ViewGroup[2];
+ private final int[] mSuggestionViewLayouts = new int[] {
+ mTextEditSuggestionsBottomWindowLayout, mTextEditSuggestionsTopWindowLayout};
+
+ public SuggestionsPopupWindow() {
+ mContainer = new PopupWindow(TextView.this.mContext, null,
+ com.android.internal.R.attr.textSuggestionsWindowStyle);
+ mContainer.setSplitTouchEnabled(true);
+ mContainer.setClippingEnabled(false);
+ mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+
+ mContainer.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
+ mContainer.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+
+ private ViewGroup getViewGroup(boolean under) {
+ final int viewIndex = under ? 0 : 1;
+ ViewGroup viewGroup = mSuggestionViews[viewIndex];
+
+ if (viewGroup == null) {
+ final int layout = mSuggestionViewLayouts[viewIndex];
+ LayoutInflater inflater = (LayoutInflater) TextView.this.mContext.
+ getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (inflater == null) {
+ throw new IllegalArgumentException(
+ "Unable to create TextEdit suggestion window inflater");
+ }
+
+ View view = inflater.inflate(layout, null);
+
+ if (! (view instanceof ViewGroup)) {
+ throw new IllegalArgumentException(
+ "Inflated TextEdit suggestion window is not a ViewGroup: " + view);
+ }
+
+ viewGroup = (ViewGroup) view;
+
+ // Inflate the suggestion items once and for all.
+ for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
+ View childView = inflater.inflate(mTextEditSuggestionItemLayout, viewGroup,
+ false);
+
+ if (! (childView instanceof TextView)) {
+ throw new IllegalArgumentException(
+ "Inflated TextEdit suggestion item is not a TextView: " + childView);
+ }
+
+ viewGroup.addView(childView);
+ childView.setOnClickListener(this);
+ }
+
+ mSuggestionViews[viewIndex] = viewGroup;
+ }
+
+ return viewGroup;
+ }
+
+ public void show() {
+ if (!(mText instanceof Editable)) return;
+
+ final int pos = TextView.this.getSelectionStart();
+ Spannable spannable = (Spannable)TextView.this.mText;
+ CorrectionSpan[] correctionSpans = spannable.getSpans(pos, pos, CorrectionSpan.class);
+ final int nbSpans = correctionSpans.length;
+
+ ViewGroup viewGroup = getViewGroup(true);
+ mContainer.setContentView(viewGroup);
+
+ int totalNbSuggestions = 0;
+ for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
+ CorrectionSpan correctionSpan = correctionSpans[spanIndex];
+ final int spanStart = spannable.getSpanStart(correctionSpan);
+ final int spanEnd = spannable.getSpanEnd(correctionSpan);
+ final Long spanRange = packRangeInLong(spanStart, spanEnd);
+
+ String[] suggestions = correctionSpan.getSuggestions();
+ int nbSuggestions = suggestions.length;
+ for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
+ TextView textView = (TextView) viewGroup.getChildAt(totalNbSuggestions);
+ textView.setText(suggestions[suggestionIndex]);
+ textView.setTag(spanRange);
+
+ totalNbSuggestions++;
+ if (totalNbSuggestions == MAX_NUMBER_SUGGESTIONS) {
+ spanIndex = nbSpans;
+ break;
+ }
+ }
+ }
+
+ if (totalNbSuggestions == 0) {
+ // TODO Replace by final text, use a dedicated layout, add a fade out timer...
+ TextView textView = (TextView) viewGroup.getChildAt(0);
+ textView.setText("No suggestions available");
+ textView.setTag(NO_SUGGESTIONS);
+ totalNbSuggestions++;
+ }
+
+ for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
+ viewGroup.getChildAt(i).setVisibility(i < totalNbSuggestions ? VISIBLE : GONE);
+ }
+
+ final int size = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+ viewGroup.measure(size, size);
+
+ positionAtCursor();
+ }
+
+ public void hide() {
+ mContainer.dismiss();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view instanceof TextView) {
+ TextView textView = (TextView) view;
+ Long range = ((Long) view.getTag());
+ if (range != NO_SUGGESTIONS) {
+ final int spanStart = extractRangeStartFromLong(range);
+ final int spanEnd = extractRangeEndFromLong(range);
+ ((Editable) mText).replace(spanStart, spanEnd, textView.getText());
+ }
+ }
+ hide();
+ }
+
+ void positionAtCursor() {
+ View contentView = mContainer.getContentView();
+ int width = contentView.getMeasuredWidth();
+ int height = contentView.getMeasuredHeight();
+ final int offset = TextView.this.getSelectionStart();
+ final int line = mLayout.getLineForOffset(offset);
+ final int lineBottom = mLayout.getLineBottom(line);
+ float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
+
+ final Rect bounds = sCursorControllerTempRect;
+ bounds.left = (int) (primaryHorizontal - width / 2.0f);
+ bounds.top = lineBottom;
+
+ bounds.right = bounds.left + width;
+ bounds.bottom = bounds.top + height;
+
+ convertFromViewportToContentCoordinates(bounds);
+
+ final int[] coords = mTempCoords;
+ TextView.this.getLocationInWindow(coords);
+ coords[0] += bounds.left;
+ coords[1] += bounds.top;
+
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ final int screenHeight = displayMetrics.heightPixels;
+
+ // Vertical clipping
+ if (coords[1] + height > screenHeight) {
+ // Try to position above current line instead
+ // TODO use top layout instead, reverse suggestion order,
+ // try full screen vertical down if it still does not fit. TBD with designers.
+
+ // Update dimensions from new view
+ contentView = mContainer.getContentView();
+ width = contentView.getMeasuredWidth();
+ height = contentView.getMeasuredHeight();
+
+ final int lineTop = mLayout.getLineTop(line);
+ final int lineHeight = lineBottom - lineTop;
+ coords[1] -= height + lineHeight;
+ }
+
+ // Horizontal clipping
+ coords[0] = Math.max(0, coords[0]);
+ coords[0] = Math.min(displayMetrics.widthPixels - width, coords[0]);
+
+ mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
+ }
+ }
+
+ void showSuggestions() {
+ if (mSuggestionsPopupWindow == null) {
+ mSuggestionsPopupWindow = new SuggestionsPopupWindow();
+ }
+ hideControllers();
+ mSuggestionsPopupWindow.show();
+ }
+
+ void hideSuggestions() {
+ if (mSuggestionsPopupWindow != null) {
+ mSuggestionsPopupWindow.hide();
+ }
+ }
+
/**
* If provided, this ActionMode.Callback will be used to create the ActionMode when text
* selection is initiated in this View.
@@ -8437,16 +8649,14 @@
}
}
- private class PastePopupMenu implements OnClickListener {
+ private class PastePopupWindow implements OnClickListener {
private final PopupWindow mContainer;
- private int mPositionX;
- private int mPositionY;
private final View[] mPasteViews = new View[4];
private final int[] mPasteViewLayouts = new int[] {
mTextEditPasteWindowLayout, mTextEditNoPasteWindowLayout,
mTextEditSidePasteWindowLayout, mTextEditSideNoPasteWindowLayout };
- public PastePopupMenu() {
+ public PastePopupWindow() {
mContainer = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
mContainer.setSplitTouchEnabled(true);
@@ -8529,14 +8739,10 @@
convertFromViewportToContentCoordinates(bounds);
- mPositionX = bounds.left;
- mPositionY = bounds.top;
-
-
final int[] coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
- coords[0] += mPositionX;
- coords[1] += mPositionY;
+ coords[0] += bounds.left;
+ coords[1] += bounds.top;
final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
if (coords[1] < 0) {
@@ -8881,7 +9087,7 @@
void hideAssociatedPopupWindow() {
// No associated popup window by default
}
-
+
public void onDetached() {
// Should be overriden to clean possible Runnable
}
@@ -8891,10 +9097,10 @@
private static final int DELAY_BEFORE_FADE_OUT = 4000;
private static final int RECENT_CUT_COPY_DURATION = 15 * 1000; // seconds
- // Used to detect taps on the insertion handle, which will affect the PastePopupMenu
+ // Used to detect taps on the insertion handle, which will affect the PastePopupWindow
private long mTouchTimer;
private float mDownPositionX, mDownPositionY;
- private PastePopupMenu mPastePopupWindow;
+ private PastePopupWindow mPastePopupWindow;
private Runnable mHider;
private Runnable mPastePopupShower;
@@ -9034,7 +9240,7 @@
void showAssociatedPopupWindow() {
if (mPastePopupWindow == null) {
// Lazy initialisation: create when actually shown only.
- mPastePopupWindow = new PastePopupMenu();
+ mPastePopupWindow = new PastePopupWindow();
}
mPastePopupWindow.show();
}
@@ -9245,6 +9451,7 @@
mEndHandle.show();
hideInsertionPointCursorController();
+ hideSuggestions();
}
public void hide() {
@@ -9272,7 +9479,7 @@
final int deltaY = y - mPreviousTapPositionY;
final int distanceSquared = deltaX * deltaX + deltaY * deltaY;
if (distanceSquared < mSquaredTouchSlopDistance) {
- startSelectionActionMode();
+ showSuggestions();
mDiscardNextActionUp = true;
}
}
@@ -9362,6 +9569,7 @@
private void hideControllers() {
hideInsertionPointCursorController();
stopSelectionActionMode();
+ hideSuggestions();
}
/**
diff --git a/core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png b/core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png
new file mode 100644
index 0000000..88be6e1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png b/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png
new file mode 100644
index 0000000..41886eb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png
Binary files differ
diff --git a/core/res/res/layout/text_edit_suggestion_item.xml b/core/res/res/layout/text_edit_suggestion_item.xml
new file mode 100644
index 0000000..a54cad2
--- /dev/null
+++ b/core/res/res/layout/text_edit_suggestion_item.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:layout_gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="@android:color/black" />
+
diff --git a/core/res/res/layout/text_edit_suggestions_bottom_window.xml b/core/res/res/layout/text_edit_suggestions_bottom_window.xml
new file mode 100644
index 0000000..588bfbd
--- /dev/null
+++ b/core/res/res/layout/text_edit_suggestions_bottom_window.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@android:drawable/text_edit_suggestions_bottom_window">
+
+</LinearLayout>
diff --git a/core/res/res/layout/text_edit_suggestions_top_window.xml b/core/res/res/layout/text_edit_suggestions_top_window.xml
new file mode 100644
index 0000000..67faa37
--- /dev/null
+++ b/core/res/res/layout/text_edit_suggestions_top_window.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@android:drawable/text_edit_suggestions_top_window">
+
+</LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 77f4e01..2cc57a9 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -525,6 +525,9 @@
<!-- Reference to a style that will be used for the window containing a text
selection anchor. -->
<attr name="textSelectHandleWindowStyle" format="reference" />
+ <!-- Reference to a style that will be used for the window containing a list of possible
+ text suggestions in an EditText. -->
+ <attr name="textSuggestionsWindowStyle" format="reference" />
<!-- Default ListPopupWindow style. -->
<attr name="listPopupWindowStyle" format="reference" />
<!-- Default PopupMenu style. -->
@@ -673,6 +676,15 @@
<!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditSideNoPasteWindowLayout" format="reference" />
+ <!-- Layout of a the view that is used to create the text suggestions popup window in an
+ EditText. This window will be displayed below the text line. -->
+ <attr name="textEditSuggestionsBottomWindowLayout" format="reference" />
+ <!-- Same as textEditSuggestionsBottomWindowLayout, but used when the popup is displayed
+ above the current line of text instead of below. -->
+ <attr name="textEditSuggestionsTopWindowLayout" format="reference" />
+ <!-- Layout of the TextView item that will populate the suggestion popup window. -->
+ <attr name="textEditSuggestionItemLayout" format="reference" />
+
<!-- Theme to use for dialogs spawned from this theme. -->
<attr name="dialogTheme" format="reference" />
<!-- Window decor layout to use in dialog mode with icons -->
@@ -2810,6 +2822,16 @@
<!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditSideNoPasteWindowLayout" />
+ <!-- Layout of a the view that is used to create the text suggestions popup window in an
+ EditText. This window will be displayed below the text line. -->
+ <attr name="textEditSuggestionsBottomWindowLayout" />
+ <!-- Same as textEditSuggestionsBottomWindowLayout, but used when the popup is displayed
+ above the current line of text instead of below. -->
+ <attr name="textEditSuggestionsTopWindowLayout" />
+ <!-- Layout of the TextView item that will populate the suggestion popup window. -->
+ <attr name="textEditSuggestionItemLayout" />
+
+
<!-- Reference to a drawable that will be drawn under the insertion cursor. -->
<attr name="textCursorDrawable" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4109ae1..d5c374d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1659,4 +1659,9 @@
<public type="style" name="Theme.Holo.Light.NoActionBar" />
+ <public type="attr" name="textSuggestionsWindowStyle" />
+ <public type="attr" name="textEditSuggestionsBottomWindowLayout" />
+ <public type="attr" name="textEditSuggestionsTopWindowLayout" />
+ <public type="attr" name="textEditSuggestionItemLayout" />
+
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f7d3c3f..1a9558d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -426,6 +426,9 @@
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
<item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
<item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
+ <item name="android:textEditSuggestionsBottomWindowLayout">?android:attr/textEditSuggestionsBottomWindowLayout</item>
+ <item name="android:textEditSuggestionsTopWindowLayout">?android:attr/textEditSuggestionsTopWindowLayout</item>
+ <item name="android:textEditSuggestionItemLayout">?android:attr/textEditSuggestionItemLayout</item>
<item name="android:textCursorDrawable">?android:attr/textCursorDrawable</item>
</style>
@@ -1047,6 +1050,17 @@
<item name="windowExitAnimation">@android:anim/fade_out</item>
</style>
+ <!-- Style for the popup window that contains text suggestions. -->
+ <style name="Widget.TextSuggestions">
+ <item name="android:popupAnimationStyle">@android:style/Animation.TextSuggestions</item>
+ </style>
+
+ <!-- Animation effects when showing/hiding the text suggestions popup window. -->
+ <style name="Animation.TextSuggestions">
+ <item name="windowEnterAnimation">@android:anim/fade_in</item>
+ <item name="windowExitAnimation">@android:anim/fade_out</item>
+ </style>
+
<style name="Widget.ActionBar">
<item name="android:background">@android:drawable/action_bar_background</item>
<item name="android:displayOptions">useLogo|showHome|showTitle</item>
@@ -1460,6 +1474,9 @@
<style name="Widget.Holo.TextSelectHandle" parent="Widget.TextSelectHandle">
</style>
+ <style name="Widget.Holo.TextSuggestions" parent="Widget.TextSuggestions">
+ </style>
+
<style name="Widget.Holo.AbsListView" parent="Widget.AbsListView">
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b127747..41085e9 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -180,6 +180,10 @@
<item name="textEditNoPasteWindowLayout">@android:layout/text_edit_no_paste_window</item>
<item name="textEditSidePasteWindowLayout">@android:layout/text_edit_side_paste_window</item>
<item name="textEditSideNoPasteWindowLayout">@android:layout/text_edit_side_no_paste_window</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.TextSuggestions</item>
+ <item name="textEditSuggestionsBottomWindowLayout">@android:layout/text_edit_suggestions_bottom_window</item>
+ <item name="textEditSuggestionsTopWindowLayout">@android:layout/text_edit_suggestions_top_window</item>
+ <item name="textEditSuggestionItemLayout">@android:layout/text_edit_suggestion_item</item>
<item name="textCursorDrawable">@null</item>
<!-- Widget styles -->
@@ -917,6 +921,7 @@
<item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@android:style/Widget.Holo.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.Holo.TextSuggestions</item>
<item name="textCursorDrawable">@android:drawable/text_cursor_holo_dark</item>
<!-- Widget styles -->
@@ -1200,6 +1205,7 @@
<item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@android:style/Widget.Holo.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.Holo.TextSuggestions</item>
<item name="textCursorDrawable">@android:drawable/text_cursor_holo_light</item>
<!-- Widget styles -->