diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/res/drawable-hdpi/btn_close_candidates_pane.9.png | bin | 936 -> 1110 bytes | |||
-rw-r--r-- | java/res/layout/candidate_divider.xml | 3 | ||||
-rw-r--r-- | java/res/layout/candidate_word.xml | 11 | ||||
-rw-r--r-- | java/res/layout/candidates_strip.xml | 6 | ||||
-rw-r--r-- | java/res/values/dimens.xml | 2 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/CandidateView.java | 97 |
6 files changed, 96 insertions, 23 deletions
diff --git a/java/res/drawable-hdpi/btn_close_candidates_pane.9.png b/java/res/drawable-hdpi/btn_close_candidates_pane.9.png Binary files differindex bdd949577..6df00f229 100644 --- a/java/res/drawable-hdpi/btn_close_candidates_pane.9.png +++ b/java/res/drawable-hdpi/btn_close_candidates_pane.9.png diff --git a/java/res/layout/candidate_divider.xml b/java/res/layout/candidate_divider.xml index 1d75e52b3..748163074 100644 --- a/java/res/layout/candidate_divider.xml +++ b/java/res/layout/candidate_divider.xml @@ -23,8 +23,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:src="@drawable/keyboard_suggest_strip_divider" - android:paddingRight="@dimen/candidate_padding" - android:paddingLeft="@dimen/candidate_padding" + android:padding="0dp" android:focusable="false" android:clickable="false" android:gravity="center_vertical|center_horizontal" /> diff --git a/java/res/layout/candidate_word.xml b/java/res/layout/candidate_word.xml index 3d2ad06e4..7b6db2fe8 100644 --- a/java/res/layout/candidate_word.xml +++ b/java/res/layout/candidate_word.xml @@ -20,9 +20,14 @@ <Button xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_height="match_parent" android:minWidth="@dimen/candidate_min_width" android:textSize="@dimen/candidate_text_size" - android:padding="0dp" + android:paddingLeft="@dimen/candidate_padding" + android:paddingTop="0dp" + android:paddingRight="@dimen/candidate_padding" + android:paddingBottom="0dp" + android:singleLine="true" + android:ellipsize="none" style="?attr/suggestionBackgroundStyle" /> diff --git a/java/res/layout/candidates_strip.xml b/java/res/layout/candidates_strip.xml index 3509a4815..ea6708ee7 100644 --- a/java/res/layout/candidates_strip.xml +++ b/java/res/layout/candidates_strip.xml @@ -24,6 +24,7 @@ > <LinearLayout android:id="@+id/candidates_strip" + android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" > @@ -83,13 +84,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" - style="?attr/suggestionsStripBackgroundStyle" /> + android:background="@null" /> <ImageButton android:id="@+id/close_candidates_pane" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" - style="?attr/suggestionsStripBackgroundStyle" /> + android:background="@null" /> </LinearLayout> </LinearLayout> <LinearLayout @@ -104,6 +105,7 @@ android:layout_weight="1.0" android:layout_width="0dp" android:layout_height="match_parent" + android:layout_gravity="center_vertical" android:textSize="@dimen/candidate_text_size" android:singleLine="true" android:ellipsize="middle" diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 54256de3c..a2332df96 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -66,7 +66,7 @@ <dimen name="candidate_strip_minimum_height">100sp</dimen> <dimen name="candidate_strip_fading_edge_length">63dip</dimen> <dimen name="candidate_strip_padding">0dip</dimen> - <dimen name="candidate_min_width">32dip</dimen> + <dimen name="candidate_min_width">44dip</dimen> <dimen name="candidate_padding">6dip</dimen> <dimen name="candidate_text_size">18dip</dimen> <!-- If the screen height in landscape is larger than the below value, then the keyboard diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 2186d608f..a5bfea0f8 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -25,11 +25,11 @@ import android.os.Message; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; +import android.text.TextPaint; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.CharacterStyle; import android.text.style.ForegroundColorSpan; -import android.text.style.StyleSpan; import android.text.style.UnderlineSpan; import android.util.AttributeSet; import android.view.Gravity; @@ -57,12 +57,11 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo public void pickSuggestionManually(int index, CharSequence word); } - private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD); private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan(); // The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}. private static final int MAX_SUGGESTIONS = 18; - private static final int UNSPECIFIED_MEASURESPEC = MeasureSpec.makeMeasureSpec( - 0, MeasureSpec.UNSPECIFIED); + private static final int MATCH_PARENT = MeasureSpec.makeMeasureSpec( + -1, MeasureSpec.UNSPECIFIED); private static final boolean DBG = LatinImeLogger.sDBG; @@ -97,6 +96,9 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo private boolean mShowingAutoCorrectionInverted; private boolean mShowingAddToDictionary; + private static final float MIN_TEXT_XSCALE = 0.4f; + private static final String ELLIPSIS = "\u2026"; + private final UiHandler mHandler = new UiHandler(this); private static class UiHandler extends StaticInnerHandlerWrapper<CandidateView> { @@ -189,7 +191,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo switch (i) { case 0: word = (TextView)findViewById(R.id.word_left); - word.setPadding(res.getDimensionPixelOffset(R.dimen.candidate_padding), 0, 0, 0); info = (TextView)findViewById(R.id.info_left); break; case 1: @@ -213,7 +214,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo mInfos.add(info); if (i > 0) { final View divider = inflater.inflate(R.layout.candidate_divider, null); - divider.measure(UNSPECIFIED_MEASURESPEC, UNSPECIFIED_MEASURESPEC); + divider.measure(MATCH_PARENT, MATCH_PARENT); mDividers.add(divider); } } @@ -278,12 +279,14 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo } } - private CharSequence getStyledCandidateWord(CharSequence word, boolean isAutoCorrect) { + private CharSequence getStyledCandidateWord(CharSequence word, TextView v, + boolean isAutoCorrect) { + v.setTypeface(Typeface.DEFAULT); if (!isAutoCorrect) return word; final Spannable spannedWord = new SpannableString(word); if ((mAutoCorrectHighlight & AUTO_CORRECT_BOLD) != 0) - spannedWord.setSpan(BOLD_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + v.setTypeface(Typeface.DEFAULT_BOLD); if ((mAutoCorrectHighlight & AUTO_CORRECT_UNDERLINE) != 0) spannedWord.setSpan(UNDERLINE_SPAN, 0, word.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); return spannedWord; @@ -320,7 +323,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo int fromIndex = NUM_CANDIDATES_IN_STRIP; final int count = Math.min(mWords.size(), suggestions.size()); closeCandidatesPane(); - mExpandCandidatesPane.setEnabled(count >= NUM_CANDIDATES_IN_STRIP); + mExpandCandidatesPane.setVisibility(count > NUM_CANDIDATES_IN_STRIP ? VISIBLE : GONE); for (int i = 0; i < count; i++) { final CharSequence suggestion = suggestions.getWord(i); if (suggestion == null) continue; @@ -341,11 +344,15 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo // the word when space is typed (valid typed word or auto corrected word). word.setTextColor(getCandidateTextColor(isAutoCorrect, isSuggestedCandidate || isPunctuationSuggestions, suggestionInfo)); - word.setText(getStyledCandidateWord(suggestion, isAutoCorrect)); - // TODO: call TextView.setTextScaleX() to fit the candidate in single line. - word.measure(UNSPECIFIED_MEASURESPEC, UNSPECIFIED_MEASURESPEC); - final int width = word.getMeasuredWidth(); - final int height = word.getMeasuredHeight(); + final CharSequence text = getStyledCandidateWord(suggestion, word, isAutoCorrect); + if (i < NUM_CANDIDATES_IN_STRIP) { + final View parent = (View)word.getParent(); + final int width = parent.getWidth() - word.getPaddingLeft() + - word.getPaddingRight(); + setTextWithAutoScaleAndEllipsis(text, width, word); + } else { + setTextWithAutoScaleAndEllipsis(text, paneWidth, word); + } final TextView info; if (DBG && suggestionInfo != null @@ -353,18 +360,23 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo info = mInfos.get(i); info.setText(suggestionInfo.getDebugString()); info.setVisibility(View.VISIBLE); - info.measure(UNSPECIFIED_MEASURESPEC, UNSPECIFIED_MEASURESPEC); } else { info = null; } if (i < NUM_CANDIDATES_IN_STRIP) { if (info != null) { + word.measure(MATCH_PARENT, MATCH_PARENT); + info.measure(MATCH_PARENT, MATCH_PARENT); + final int width = word.getMeasuredWidth(); final int infoWidth = info.getMeasuredWidth(); FrameLayoutCompatUtils.placeViewAt( info, width - infoWidth, 0, infoWidth, info.getMeasuredHeight()); } } else { + word.measure(MATCH_PARENT, MATCH_PARENT); + final int width = word.getMeasuredWidth(); + final int height = word.getMeasuredHeight(); // TODO: Handle overflow case. if (dividerWidth + x + width >= paneWidth) { centeringCandidates(fromIndex, i - 1, x, paneWidth); @@ -385,6 +397,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo word, x, y + (mCandidateStripHeight - height) / 2, width, height); if (info != null) { mCandidatesPane.addView(info); + info.measure(MATCH_PARENT, MATCH_PARENT); final int infoWidth = info.getMeasuredWidth(); FrameLayoutCompatUtils.placeViewAt( info, x + width - infoWidth, y, infoWidth, info.getMeasuredHeight()); @@ -423,6 +436,60 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo } } + private static void setTextWithAutoScaleAndEllipsis(CharSequence text, int w, TextView v) { + // To prevent partially rendered character at the end of text, subtract few extra pixels + // from the width. + final int width = w - 4; + + final TextPaint paint = v.getPaint(); + final int textWidth = getTextWidth(text, paint, 1.0f); + if (textWidth < width || textWidth == 0 || width <= 0) { + v.setTextScaleX(1.0f); + v.setText(text); + return; + } + + final float scaleX = Math.min((float)width / textWidth, 1.0f); + if (scaleX >= MIN_TEXT_XSCALE) { + v.setTextScaleX(scaleX); + v.setText(text); + return; + } + + final int truncatedWidth = width - getTextWidth(ELLIPSIS, paint, MIN_TEXT_XSCALE); + final CharSequence ellipsized = getTextEllipsizedAtStart(text, paint, truncatedWidth); + v.setTextScaleX(MIN_TEXT_XSCALE); + v.setText(ELLIPSIS); + v.append(ellipsized); + } + + private static int getTextWidth(CharSequence text, TextPaint paint, float scaleX) { + if (TextUtils.isEmpty(text)) return 0; + final int len = text.length(); + final float[] widths = new float[len]; + paint.setTextScaleX(scaleX); + final int count = paint.getTextWidths(text, 0, len, widths); + float width = 0; + for (int i = 0; i < count; i++) { + width += widths[i]; + } + return (int)Math.round(width + 0.5); + } + + private static CharSequence getTextEllipsizedAtStart(CharSequence text, TextPaint paint, + int maxWidth) { + final int len = text.length(); + final float[] widths = new float[len]; + final int count = paint.getTextWidths(text, 0, len, widths); + float width = 0; + for (int i = count - 1; i >= 0; i--) { + width += widths[i]; + if (width > maxWidth) + return text.subSequence(i + 1, len); + } + return text; + } + private void expandCandidatesPane() { mExpandCandidatesPane.setVisibility(View.GONE); mCloseCandidatesPane.setVisibility(View.VISIBLE); |