Refactor SuggestionStripLayoutHelper a bit

Bug: 9059710
Change-Id: Ief12029bad75d4dc78090ab97555aece01b873de
main
Tadashi G. Takaoka 2013-05-30 23:47:54 +09:00
parent 70c2dcffa3
commit a0c3e02d71
5 changed files with 134 additions and 127 deletions

View File

@ -161,7 +161,7 @@
<declare-styleable name="SuggestionStripView"> <declare-styleable name="SuggestionStripView">
<attr name="suggestionStripOption" format="integer"> <attr name="suggestionStripOption" format="integer">
<!-- This should be aligned with SuggestionStripViewParams.AUTO_CORRECT_* and etc. --> <!-- This should be aligned with SuggestionStripLayoutHelper.AUTO_CORRECT_* and etc. -->
<flag name="autoCorrectBold" value="0x01" /> <flag name="autoCorrectBold" value="0x01" />
<flag name="autoCorrectUnderline" value="0x02" /> <flag name="autoCorrectUnderline" value="0x02" />
<flag name="validTypedWordBold" value="0x04" /> <flag name="validTypedWordBold" value="0x04" />

View File

@ -24,6 +24,9 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
public final class SuggestedWords { public final class SuggestedWords {
public static final int INDEX_OF_TYPED_WORD = 0;
public static final int INDEX_OF_AUTO_CORRECTION = 1;
private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST =
CollectionUtils.newArrayList(0); CollectionUtils.newArrayList(0);
public static final SuggestedWords EMPTY = new SuggestedWords( public static final SuggestedWords EMPTY = new SuggestedWords(
@ -61,12 +64,12 @@ public final class SuggestedWords {
return mSuggestedWordInfoList.size(); return mSuggestedWordInfoList.size();
} }
public String getWord(int pos) { public String getWord(final int index) {
return mSuggestedWordInfoList.get(pos).mWord; return mSuggestedWordInfoList.get(index).mWord;
} }
public SuggestedWordInfo getInfo(int pos) { public SuggestedWordInfo getInfo(final int index) {
return mSuggestedWordInfoList.get(pos); return mSuggestedWordInfoList.get(index);
} }
public boolean willAutoCorrect() { public boolean willAutoCorrect() {
@ -108,8 +111,8 @@ public final class SuggestedWords {
SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED)); SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED));
alreadySeen.add(typedWord.toString()); alreadySeen.add(typedWord.toString());
final int previousSize = previousSuggestions.size(); final int previousSize = previousSuggestions.size();
for (int pos = 1; pos < previousSize; pos++) { for (int index = 1; index < previousSize; index++) {
final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(pos); final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(index);
final String prevWord = prevWordInfo.mWord; final String prevWord = prevWordInfo.mWord;
// Filter out duplicate suggestion. // Filter out duplicate suggestion.
if (!alreadySeen.contains(prevWord)) { if (!alreadySeen.contains(prevWord)) {

View File

@ -61,7 +61,7 @@ public final class MoreSuggestions extends Keyboard {
super(); super();
} }
public int layout(final SuggestedWords suggestedWords, final int fromPos, public int layout(final SuggestedWords suggestedWords, final int fromIndex,
final int maxWidth, final int minWidth, final int maxRow, final Paint paint, final int maxWidth, final int minWidth, final int maxRow, final Paint paint,
final Resources res) { final Resources res) {
clearKeys(); clearKeys();
@ -70,53 +70,54 @@ public final class MoreSuggestions extends Keyboard {
final float padding = res.getDimension(R.dimen.more_suggestions_key_horizontal_padding); final float padding = res.getDimension(R.dimen.more_suggestions_key_horizontal_padding);
int row = 0; int row = 0;
int pos = fromPos, rowStartPos = fromPos; int index = fromIndex;
int rowStartIndex = fromIndex;
final int size = Math.min(suggestedWords.size(), SuggestionStripView.MAX_SUGGESTIONS); final int size = Math.min(suggestedWords.size(), SuggestionStripView.MAX_SUGGESTIONS);
while (pos < size) { while (index < size) {
final String word = suggestedWords.getWord(pos); final String word = suggestedWords.getWord(index);
// TODO: Should take care of text x-scaling. // TODO: Should take care of text x-scaling.
mWidths[pos] = (int)(TypefaceUtils.getLabelWidth(word, paint) + padding); mWidths[index] = (int)(TypefaceUtils.getLabelWidth(word, paint) + padding);
final int numColumn = pos - rowStartPos + 1; final int numColumn = index - rowStartIndex + 1;
final int columnWidth = final int columnWidth =
(maxWidth - mDividerWidth * (numColumn - 1)) / numColumn; (maxWidth - mDividerWidth * (numColumn - 1)) / numColumn;
if (numColumn > MAX_COLUMNS_IN_ROW if (numColumn > MAX_COLUMNS_IN_ROW
|| !fitInWidth(rowStartPos, pos + 1, columnWidth)) { || !fitInWidth(rowStartIndex, index + 1, columnWidth)) {
if ((row + 1) >= maxRow) { if ((row + 1) >= maxRow) {
break; break;
} }
mNumColumnsInRow[row] = pos - rowStartPos; mNumColumnsInRow[row] = index - rowStartIndex;
rowStartPos = pos; rowStartIndex = index;
row++; row++;
} }
mColumnOrders[pos] = pos - rowStartPos; mColumnOrders[index] = index - rowStartIndex;
mRowNumbers[pos] = row; mRowNumbers[index] = row;
pos++; index++;
} }
mNumColumnsInRow[row] = pos - rowStartPos; mNumColumnsInRow[row] = index - rowStartIndex;
mNumRows = row + 1; mNumRows = row + 1;
mBaseWidth = mOccupiedWidth = Math.max( mBaseWidth = mOccupiedWidth = Math.max(
minWidth, calcurateMaxRowWidth(fromPos, pos)); minWidth, calcurateMaxRowWidth(fromIndex, index));
mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap; mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
return pos - fromPos; return index - fromIndex;
} }
private boolean fitInWidth(final int startPos, final int endPos, final int width) { private boolean fitInWidth(final int startIndex, final int endIndex, final int width) {
for (int pos = startPos; pos < endPos; pos++) { for (int index = startIndex; index < endIndex; index++) {
if (mWidths[pos] > width) if (mWidths[index] > width)
return false; return false;
} }
return true; return true;
} }
private int calcurateMaxRowWidth(final int startPos, final int endPos) { private int calcurateMaxRowWidth(final int startIndex, final int endIndex) {
int maxRowWidth = 0; int maxRowWidth = 0;
int pos = startPos; int index = startIndex;
for (int row = 0; row < mNumRows; row++) { for (int row = 0; row < mNumRows; row++) {
final int numColumnInRow = mNumColumnsInRow[row]; final int numColumnInRow = mNumColumnsInRow[row];
int maxKeyWidth = 0; int maxKeyWidth = 0;
while (pos < endPos && mRowNumbers[pos] == row) { while (index < endIndex && mRowNumbers[index] == row) {
maxKeyWidth = Math.max(maxKeyWidth, mWidths[pos]); maxKeyWidth = Math.max(maxKeyWidth, mWidths[index]);
pos++; index++;
} }
maxRowWidth = Math.max(maxRowWidth, maxRowWidth = Math.max(maxRowWidth,
maxKeyWidth * numColumnInRow + mDividerWidth * (numColumnInRow - 1)); maxKeyWidth * numColumnInRow + mDividerWidth * (numColumnInRow - 1));
@ -130,40 +131,40 @@ public final class MoreSuggestions extends Keyboard {
{ 2, 0, 1}, { 2, 0, 1},
}; };
public int getNumColumnInRow(final int pos) { public int getNumColumnInRow(final int index) {
return mNumColumnsInRow[mRowNumbers[pos]]; return mNumColumnsInRow[mRowNumbers[index]];
} }
public int getColumnNumber(final int pos) { public int getColumnNumber(final int index) {
final int columnOrder = mColumnOrders[pos]; final int columnOrder = mColumnOrders[index];
final int numColumn = getNumColumnInRow(pos); final int numColumn = getNumColumnInRow(index);
return COLUMN_ORDER_TO_NUMBER[numColumn - 1][columnOrder]; return COLUMN_ORDER_TO_NUMBER[numColumn - 1][columnOrder];
} }
public int getX(final int pos) { public int getX(final int index) {
final int columnNumber = getColumnNumber(pos); final int columnNumber = getColumnNumber(index);
return columnNumber * (getWidth(pos) + mDividerWidth); return columnNumber * (getWidth(index) + mDividerWidth);
} }
public int getY(final int pos) { public int getY(final int index) {
final int row = mRowNumbers[pos]; final int row = mRowNumbers[index];
return (mNumRows -1 - row) * mDefaultRowHeight + mTopPadding; return (mNumRows -1 - row) * mDefaultRowHeight + mTopPadding;
} }
public int getWidth(final int pos) { public int getWidth(final int index) {
final int numColumnInRow = getNumColumnInRow(pos); final int numColumnInRow = getNumColumnInRow(index);
return (mOccupiedWidth - mDividerWidth * (numColumnInRow - 1)) / numColumnInRow; return (mOccupiedWidth - mDividerWidth * (numColumnInRow - 1)) / numColumnInRow;
} }
public void markAsEdgeKey(final Key key, final int pos) { public void markAsEdgeKey(final Key key, final int index) {
final int row = mRowNumbers[pos]; final int row = mRowNumbers[index];
if (row == 0) if (row == 0)
key.markAsBottomEdge(this); key.markAsBottomEdge(this);
if (row == mNumRows - 1) if (row == mNumRows - 1)
key.markAsTopEdge(this); key.markAsTopEdge(this);
final int numColumnInRow = mNumColumnsInRow[row]; final int numColumnInRow = mNumColumnsInRow[row];
final int column = getColumnNumber(pos); final int column = getColumnNumber(index);
if (column == 0) if (column == 0)
key.markAsLeftEdge(this); key.markAsLeftEdge(this);
if (column == numColumnInRow - 1) if (column == numColumnInRow - 1)
@ -174,15 +175,15 @@ public final class MoreSuggestions extends Keyboard {
public static final class Builder extends KeyboardBuilder<MoreSuggestionsParam> { public static final class Builder extends KeyboardBuilder<MoreSuggestionsParam> {
private final MoreSuggestionsView mPaneView; private final MoreSuggestionsView mPaneView;
private SuggestedWords mSuggestedWords; private SuggestedWords mSuggestedWords;
private int mFromPos; private int mFromIndex;
private int mToPos; private int mToIndex;
public Builder(final Context context, final MoreSuggestionsView paneView) { public Builder(final Context context, final MoreSuggestionsView paneView) {
super(context, new MoreSuggestionsParam()); super(context, new MoreSuggestionsParam());
mPaneView = paneView; mPaneView = paneView;
} }
public Builder layout(final SuggestedWords suggestedWords, final int fromPos, public Builder layout(final SuggestedWords suggestedWords, final int fromIndex,
final int maxWidth, final int minWidth, final int maxRow, final int maxWidth, final int minWidth, final int maxRow,
final Keyboard parentKeyboard) { final Keyboard parentKeyboard) {
final int xmlId = R.xml.kbd_suggestions_pane_template; final int xmlId = R.xml.kbd_suggestions_pane_template;
@ -190,10 +191,10 @@ public final class MoreSuggestions extends Keyboard {
mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2; mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
mPaneView.updateKeyboardGeometry(mParams.mDefaultRowHeight); mPaneView.updateKeyboardGeometry(mParams.mDefaultRowHeight);
final int count = mParams.layout(suggestedWords, fromPos, maxWidth, minWidth, maxRow, final int count = mParams.layout(suggestedWords, fromIndex, maxWidth, minWidth, maxRow,
mPaneView.newLabelPaint(null /* key */), mResources); mPaneView.newLabelPaint(null /* key */), mResources);
mFromPos = fromPos; mFromIndex = fromIndex;
mToPos = fromPos + count; mToIndex = fromIndex + count;
mSuggestedWords = suggestedWords; mSuggestedWords = suggestedWords;
return this; return this;
} }
@ -201,20 +202,20 @@ public final class MoreSuggestions extends Keyboard {
@Override @Override
public MoreSuggestions build() { public MoreSuggestions build() {
final MoreSuggestionsParam params = mParams; final MoreSuggestionsParam params = mParams;
for (int pos = mFromPos; pos < mToPos; pos++) { for (int index = mFromIndex; index < mToIndex; index++) {
final int x = params.getX(pos); final int x = params.getX(index);
final int y = params.getY(pos); final int y = params.getY(index);
final int width = params.getWidth(pos); final int width = params.getWidth(index);
final String word = mSuggestedWords.getWord(pos); final String word = mSuggestedWords.getWord(index);
final String info = Utils.getDebugInfo(mSuggestedWords, pos); final String info = Utils.getDebugInfo(mSuggestedWords, index);
final int index = pos + SUGGESTION_CODE_BASE; final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE;
final Key key = new Key( final Key key = new Key(
params, word, info, KeyboardIconsSet.ICON_UNDEFINED, index, null, x, y, params, word, info, KeyboardIconsSet.ICON_UNDEFINED, indexInMoreSuggestions,
width, params.mDefaultRowHeight, 0); null, x, y, width, params.mDefaultRowHeight, 0);
params.markAsEdgeKey(key, pos); params.markAsEdgeKey(key, index);
params.onAddKey(key); params.onAddKey(key);
final int columnNumber = params.getColumnNumber(pos); final int columnNumber = params.getColumnNumber(index);
final int numColumnInRow = params.getNumColumnInRow(pos); final int numColumnInRow = params.getNumColumnInRow(index);
if (columnNumber < numColumnInRow - 1) { if (columnNumber < numColumnInRow - 1) {
final Divider divider = new Divider(params, params.mDivider, x + width, y, final Divider divider = new Divider(params, params.mDivider, x + width, y,
params.mDividerWidth, params.mDefaultRowHeight); params.mDividerWidth, params.mDefaultRowHeight);

View File

@ -23,9 +23,9 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.Spannable; import android.text.Spannable;
@ -40,14 +40,13 @@ import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.android.inputmethod.keyboard.ViewLayoutUtils; import com.android.inputmethod.keyboard.ViewLayoutUtils;
import com.android.inputmethod.latin.AutoCorrection; import com.android.inputmethod.latin.AutoCorrection;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResourceUtils; import com.android.inputmethod.latin.ResourceUtils;
@ -71,7 +70,11 @@ final class SuggestionStripLayoutHelper {
private int mMaxMoreSuggestionsRow; private int mMaxMoreSuggestionsRow;
public final float mMinMoreSuggestionsWidth; public final float mMinMoreSuggestionsWidth;
public final int mMoreSuggestionsBottomGap; public final int mMoreSuggestionsBottomGap;
public boolean mMoreSuggestionsAvailable;
// The index of these {@link ArrayList} is the position in the suggestion strip. The indices
// increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
// The position of the most important suggestion is in {@link #mCenterPositionInStrip}
private final ArrayList<TextView> mWordViews; private final ArrayList<TextView> mWordViews;
private final ArrayList<View> mDividerViews; private final ArrayList<View> mDividerViews;
private final ArrayList<TextView> mDebugInfoViews; private final ArrayList<TextView> mDebugInfoViews;
@ -89,16 +92,14 @@ final class SuggestionStripLayoutHelper {
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD); private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan(); private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
private final int mSuggestionStripOption;
// These constants are the flag values of
// {@link R.styleable#SuggestionStripView_suggestionStripOption} attribute.
private static final int AUTO_CORRECT_BOLD = 0x01; private static final int AUTO_CORRECT_BOLD = 0x01;
private static final int AUTO_CORRECT_UNDERLINE = 0x02; private static final int AUTO_CORRECT_UNDERLINE = 0x02;
private static final int VALID_TYPED_WORD_BOLD = 0x04; private static final int VALID_TYPED_WORD_BOLD = 0x04;
private final int mSuggestionStripOption;
private final ArrayList<CharSequence> mWords = CollectionUtils.newArrayList();
public boolean mMoreSuggestionsAvailable;
private final TextView mWordToSaveView; private final TextView mWordToSaveView;
private final TextView mLeftwardsArrowView; private final TextView mLeftwardsArrowView;
private final TextView mHintToSaveView; private final TextView mHintToSaveView;
@ -205,7 +206,7 @@ final class SuggestionStripLayoutHelper {
return new BitmapDrawable(res, buffer); return new BitmapDrawable(res, buffer);
} }
private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords, private CharSequence getStyledSuggestedWord(final SuggestedWords suggestedWords,
final int indexInSuggestedWords) { final int indexInSuggestedWords) {
final String word = suggestedWords.getWord(indexInSuggestedWords); final String word = suggestedWords.getWord(indexInSuggestedWords);
final boolean isAutoCorrect = indexInSuggestedWords == 1 final boolean isAutoCorrect = indexInSuggestedWords == 1
@ -233,7 +234,8 @@ final class SuggestionStripLayoutHelper {
final SuggestedWords suggestedWords) { final SuggestedWords suggestedWords) {
// TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
// suggestions. // suggestions.
final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() ? 1 : 0; final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect()
? SuggestedWords.INDEX_OF_AUTO_CORRECTION : SuggestedWords.INDEX_OF_TYPED_WORD;
if (positionInStrip == mCenterPositionInStrip) { if (positionInStrip == mCenterPositionInStrip) {
return mostImportantIndexInSuggestedWords; return mostImportantIndexInSuggestedWords;
} }
@ -245,10 +247,9 @@ final class SuggestionStripLayoutHelper {
private int getSuggestionTextColor(final int positionInStrip, private int getSuggestionTextColor(final int positionInStrip,
final SuggestedWords suggestedWords) { final SuggestedWords suggestedWords) {
final int indexInSuggestedWords = getIndexInSuggestedWords( final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords);
positionInStrip, suggestedWords);
// TODO: Need to revisit this logic with bigram suggestions // TODO: Need to revisit this logic with bigram suggestions
final boolean isSuggested = (indexInSuggestedWords != 0); final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
final int color; final int color;
if (positionInStrip == mCenterPositionInStrip && suggestedWords.willAutoCorrect()) { if (positionInStrip == mCenterPositionInStrip && suggestedWords.willAutoCorrect()) {
@ -265,7 +266,8 @@ final class SuggestionStripLayoutHelper {
// is in slot 1. // is in slot 1.
if (positionInStrip == mCenterPositionInStrip if (positionInStrip == mCenterPositionInStrip
&& AutoCorrection.shouldBlockAutoCorrectionBySafetyNet( && AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
suggestedWords.getWord(1), suggestedWords.getWord(0))) { suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION),
suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD))) {
return 0xFFFF0000; return 0xFFFF0000;
} }
} }
@ -296,7 +298,7 @@ final class SuggestionStripLayoutHelper {
} }
final int countInStrip = mSuggestionsCountInStrip; final int countInStrip = mSuggestionsCountInStrip;
setupWords(suggestedWords, countInStrip); setupWordViewsTextAndColor(suggestedWords, countInStrip);
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip); mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
int x = 0; int x = 0;
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) { for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
@ -308,41 +310,37 @@ final class SuggestionStripLayoutHelper {
} }
final int width = getSuggestionWidth(positionInStrip, placerView.getWidth()); final int width = getSuggestionWidth(positionInStrip, placerView.getWidth());
final TextView wordView = layoutWord(suggestedWords, positionInStrip, width); final TextView wordView = layoutWord(positionInStrip, width);
stripView.addView(wordView); stripView.addView(wordView);
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip), setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
ViewGroup.LayoutParams.MATCH_PARENT); ViewGroup.LayoutParams.MATCH_PARENT);
x += wordView.getMeasuredWidth(); x += wordView.getMeasuredWidth();
if (SuggestionStripView.DBG) { if (SuggestionStripView.DBG) {
layoutDebugInfo(suggestedWords, positionInStrip, placerView, x); layoutDebugInfo(positionInStrip, placerView, x);
} }
} }
} }
/** /**
* Format appropriately the suggested word indirectly specified by * Format appropriately the suggested word in {@link #mWordViews} specified by
* <code>positionInStrip</code> as text in a corresponding {@link TextView}. When the * <code>positionInStrip</code>. When the suggested word doesn't exist, the corresponding
* suggested word doesn't exist, the corresponding {@link TextView} will be disabled * {@link TextView} will be disabled and never respond to user interaction. The suggested word
* and never respond to user interaction. The suggested word may be shrunk or ellipsized to * may be shrunk or ellipsized to fit in the specified width.
* fit in the specified width.
* *
* The <code>positionInStrip</code> argument is the index in the suggestion strip. The indices * The <code>positionInStrip</code> argument is the index in the suggestion strip. The indices
* increase towards the right for LTR scripts and the left for RTL scripts, starting with 0. * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
* The index of the most important suggestion is in {@link #mCenterPositionInStrip}. This * The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This
* usually doesn't match the index in <code>suggedtedWords</code> -- see * usually doesn't match the index in <code>suggedtedWords</code> -- see
* {@link #getIndexInSuggestedWords(int,SuggestedWords)}. * {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
* *
* @param suggestedWords the list of suggestions. * @param positionInStrip the position in the suggestion strip.
* @param positionInStrip the in the suggestion strip.
* @param width the maximum width for layout in pixels. * @param width the maximum width for layout in pixels.
* @return the {@link TextView} containing the suggested word appropriately formatted. * @return the {@link TextView} containing the suggested word appropriately formatted.
*/ */
private TextView layoutWord(final SuggestedWords suggestedWords, final int positionInStrip, private TextView layoutWord(final int positionInStrip, final int width) {
final int width) { final TextView wordView = mWordViews.get(positionInStrip);
final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords); final CharSequence word = wordView.getText();
final CharSequence word = mWords.get(indexInSuggestedWords);
final TextView wordView = mWordViews.get(indexInSuggestedWords);
if (positionInStrip == mCenterPositionInStrip && mMoreSuggestionsAvailable) { if (positionInStrip == mCenterPositionInStrip && mMoreSuggestionsAvailable) {
// TODO: This "more suggestions hint" should have a nicely designed icon. // TODO: This "more suggestions hint" should have a nicely designed icon.
wordView.setCompoundDrawablesWithIntrinsicBounds( wordView.setCompoundDrawablesWithIntrinsicBounds(
@ -355,7 +353,6 @@ final class SuggestionStripLayoutHelper {
// Disable this suggestion if the suggestion is null or empty. // Disable this suggestion if the suggestion is null or empty.
wordView.setEnabled(!TextUtils.isEmpty(word)); wordView.setEnabled(!TextUtils.isEmpty(word));
wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
final CharSequence text = getEllipsizedText(word, width, wordView.getPaint()); final CharSequence text = getEllipsizedText(word, width, wordView.getPaint());
final float scaleX = wordView.getTextScaleX(); final float scaleX = wordView.getTextScaleX();
wordView.setText(text); // TextView.setText() resets text scale x to 1.0. wordView.setText(text); // TextView.setText() resets text scale x to 1.0.
@ -363,18 +360,13 @@ final class SuggestionStripLayoutHelper {
return wordView; return wordView;
} }
private void layoutDebugInfo(final SuggestedWords suggestedWords, final int positionInStrip, private void layoutDebugInfo(final int positionInStrip, final ViewGroup placerView,
final ViewGroup placerView, final int x) { final int x) {
final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords); final TextView debugInfoView = mDebugInfoViews.get(positionInStrip);
if (indexInSuggestedWords >= suggestedWords.size()) { final CharSequence debugInfo = debugInfoView.getText();
return;
}
final String debugInfo = Utils.getDebugInfo(suggestedWords, indexInSuggestedWords);
if (debugInfo == null) { if (debugInfo == null) {
return; return;
} }
final TextView debugInfoView = mDebugInfoViews.get(indexInSuggestedWords);
debugInfoView.setText(debugInfo);
placerView.addView(debugInfoView); placerView.addView(debugInfoView);
debugInfoView.measure( debugInfoView.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@ -399,39 +391,52 @@ final class SuggestionStripLayoutHelper {
return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1); return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
} }
private void setupWords(final SuggestedWords suggestedWords, final int countInStrip) { private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords,
mWords.clear(); final int countInStrip) {
final int count = Math.min(suggestedWords.size(), countInStrip); final int count = Math.min(suggestedWords.size(), countInStrip);
for (int pos = 0; pos < count; pos++) { for (int positionInStrip = 0; positionInStrip < count; positionInStrip++) {
final CharSequence styled = getStyledSuggestionWord(suggestedWords, pos); final int indexInSuggestedWords =
mWords.add(styled); getIndexInSuggestedWords(positionInStrip, suggestedWords);
final TextView wordView = mWordViews.get(positionInStrip);
// {@link TextView#getTag()} is used to get the index in suggestedWords at
// {@link SuggestionStripView#onClick(View)}.
wordView.setTag(indexInSuggestedWords);
wordView.setText(getStyledSuggestedWord(suggestedWords, indexInSuggestedWords));
wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(
Utils.getDebugInfo(suggestedWords, indexInSuggestedWords));
}
} }
for (int pos = count; pos < countInStrip; pos++) { for (int positionInStrip = count; positionInStrip < countInStrip; positionInStrip++) {
// Make this inactive for touches in layout(). mWordViews.get(positionInStrip).setText(null);
mWords.add(null); // Make this inactive for touches in {@link #layoutWord(int,int)}.
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(null);
}
} }
} }
private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords, private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
final ViewGroup stripView) { final ViewGroup stripView) {
final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP); final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) { for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
if (indexInStrip != 0) { if (positionInStrip != 0) {
// Add divider if this isn't the left most suggestion in suggestions strip. // Add divider if this isn't the left most suggestion in suggestions strip.
addDivider(stripView, mDividerViews.get(indexInStrip)); addDivider(stripView, mDividerViews.get(positionInStrip));
} }
final TextView word = mWordViews.get(indexInStrip); final TextView wordView = mWordViews.get(positionInStrip);
word.setEnabled(true); wordView.setEnabled(true);
word.setTextColor(mColorAutoCorrect); wordView.setTextColor(mColorAutoCorrect);
final String text = suggestedWords.getWord(indexInStrip); final String punctuation = suggestedWords.getWord(positionInStrip);
word.setText(text); wordView.setText(punctuation);
word.setTextScaleX(1.0f); wordView.setTextScaleX(1.0f);
word.setCompoundDrawables(null, null, null, null); wordView.setCompoundDrawables(null, null, null, null);
stripView.addView(word); stripView.addView(wordView);
setLayoutWeight(word, 1.0f, mSuggestionsStripHeight); setLayoutWeight(wordView, 1.0f, mSuggestionsStripHeight);
} }
mMoreSuggestionsAvailable = false; mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
} }
public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView, public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,

View File

@ -93,12 +93,10 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip); mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) { for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) {
final TextView word = (TextView)inflater.inflate(R.layout.suggestion_word, null); final TextView word = (TextView)inflater.inflate(R.layout.suggestion_word, null);
word.setTag(pos);
word.setOnClickListener(this); word.setOnClickListener(this);
word.setOnLongClickListener(this); word.setOnLongClickListener(this);
mWordViews.add(word); mWordViews.add(word);
final View divider = inflater.inflate(R.layout.suggestion_divider, null); final View divider = inflater.inflate(R.layout.suggestion_divider, null);
divider.setTag(pos);
divider.setOnClickListener(this); divider.setOnClickListener(this);
mDividerViews.add(divider); mDividerViews.add(divider);
mDebugInfoViews.add((TextView)inflater.inflate(R.layout.suggestion_info, null)); mDebugInfoViews.add((TextView)inflater.inflate(R.layout.suggestion_info, null));