diff options
Diffstat (limited to 'java/src')
7 files changed, 269 insertions, 106 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java b/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java new file mode 100644 index 000000000..a062298f2 --- /dev/null +++ b/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2013 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. + */ + +package com.android.inputmethod.dictionarypack; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.Button; +import android.widget.FrameLayout; + +import com.android.inputmethod.latin.R; + +/** + * A view that handles buttons inside it according to a status. + */ +public class ButtonSwitcher extends FrameLayout { + // Animation directions + public static final int ANIMATION_IN = 1; + public static final int ANIMATION_OUT = 2; + + public ButtonSwitcher(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ButtonSwitcher(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setText(final CharSequence text) { + ((Button)findViewById(R.id.dict_install_button)).setText(text); + } + + public void setInternalButtonVisiblility(final int visibility) { + findViewById(R.id.dict_install_button).setVisibility(visibility); + } + + public void setInternalOnClickListener(final OnClickListener listener) { + findViewById(R.id.dict_install_button).setOnClickListener(listener); + } + + public void animateButton(final int direction) { + final View button = findViewById(R.id.dict_install_button); + final float outerX = getWidth(); + final float innerX = button.getX() - button.getTranslationX(); + if (View.INVISIBLE == button.getVisibility()) { + button.setTranslationX(outerX - innerX); + button.setVisibility(View.VISIBLE); + } + if (ANIMATION_IN == direction) { + button.animate().translationX(0); + } else { + button.animate().translationX(outerX - innerX); + } + } +} diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java new file mode 100644 index 000000000..8975d69a8 --- /dev/null +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2013 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. + */ + +package com.android.inputmethod.dictionarypack; + +import com.android.inputmethod.latin.CollectionUtils; + +import java.util.HashMap; + +/** + * Helper class to maintain the interface state of word list preferences. + * + * This is necessary because the views are created on-demand by calling code. There are many + * situations where views are renewed with little relation with user interaction. For example, + * when scrolling, the view is reused so it doesn't keep its state, which means we need to keep + * it separately. Also whenever the underlying dictionary list undergoes a change (for example, + * update the metadata, or finish downloading) the whole list has to be thrown out and recreated + * in case some dictionaries appeared, disappeared, changed states etc. + */ +public class DictionaryListInterfaceState { + private static class State { + public boolean mOpen = false; + public int mStatus = MetadataDbHelper.STATUS_UNKNOWN; + } + + private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap(); + + public boolean isOpen(final String wordlistId) { + final State state = mWordlistToState.get(wordlistId); + if (null == state) return false; + return state.mOpen; + } + + public void setOpen(final String wordlistId, final int status) { + final State newState; + final State state = mWordlistToState.get(wordlistId); + newState = null == state ? new State() : state; + newState.mOpen = true; + newState.mStatus = status; + mWordlistToState.put(wordlistId, newState); + } + + public void closeAll() { + for (final State state : mWordlistToState.values()) { + state.mOpen = false; + } + } +} diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java index 9e27c1f3f..aa1e9b9cf 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java @@ -64,6 +64,8 @@ public final class DictionarySettingsFragment extends PreferenceFragment private ConnectivityManager mConnectivityManager; private MenuItem mUpdateNowMenu; private boolean mChangedSettings; + private DictionaryListInterfaceState mDictionaryListInterfaceState = + new DictionaryListInterfaceState(); private final BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() { @Override @@ -297,8 +299,9 @@ public final class DictionarySettingsFragment extends PreferenceFragment final String key = matchLevelString + "." + description + "." + wordlistId; final WordListPreference existingPref = prefList.get(key); if (null == existingPref || hasPriority(status, existingPref.mStatus)) { - final WordListPreference pref = new WordListPreference(activity, mClientId, - wordlistId, version, locale, description, status); + final WordListPreference pref = new WordListPreference(activity, + mDictionaryListInterfaceState, mClientId, wordlistId, version, locale, + description, status); prefList.put(key, pref); } } while (cursor.moveToNext()); diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java index f042795dd..f1c022808 100644 --- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java +++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java @@ -23,7 +23,6 @@ import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; -import android.widget.Button; import android.widget.ListView; import com.android.inputmethod.latin.R; @@ -43,7 +42,6 @@ public final class WordListPreference extends Preference { // What to display in the "status" field when we receive unknown data as a status from // the content provider. Empty string sounds sensible. static final private String NO_STATUS_MESSAGE = ""; - static final private int NOT_AN_INDEX = -1; /// Actions static final private int ACTION_UNKNOWN = 0; @@ -62,21 +60,19 @@ public final class WordListPreference extends Preference { // The status public int mStatus; - // Animation directions - static final private int ANIMATION_IN = 1; - static final private int ANIMATION_OUT = 2; - - private static int sLastClickedIndex = NOT_AN_INDEX; - private static String sLastClickedWordlistId = null; + private final DictionaryListInterfaceState mInterfaceState; private final OnWordListPreferenceClick mPreferenceClickHandler = new OnWordListPreferenceClick(); private final OnActionButtonClick mActionButtonClickHandler = new OnActionButtonClick(); - public WordListPreference(final Context context, final String clientId, final String wordlistId, - final int version, final Locale locale, final String description, final int status) { + public WordListPreference(final Context context, + final DictionaryListInterfaceState dictionaryListInterfaceState, final String clientId, + final String wordlistId, final int version, final Locale locale, + final String description, final int status) { super(context, null); mContext = context; + mInterfaceState = dictionaryListInterfaceState; mClientId = clientId; mVersion = version; mWordlistId = wordlistId; @@ -191,53 +187,48 @@ public final class WordListPreference extends Preference { protected void onBindView(final View view) { super.onBindView(view); ((ViewGroup)view).setLayoutTransition(null); - final Button button = (Button)view.findViewById(R.id.wordlist_button); - button.setText(getButtonLabel(mStatus)); - // String identity match. This is an ==, not an .equals, on purpose. - button.setVisibility(mWordlistId == sLastClickedWordlistId ? View.VISIBLE : View.INVISIBLE); - button.setOnClickListener(mActionButtonClickHandler); + final ButtonSwitcher buttonSwitcher = + (ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher); + buttonSwitcher.setText(getButtonLabel(mStatus)); + buttonSwitcher.setInternalButtonVisiblility(mInterfaceState.isOpen(mWordlistId) ? + View.VISIBLE : View.INVISIBLE); + buttonSwitcher.setInternalOnClickListener(mActionButtonClickHandler); view.setOnClickListener(mPreferenceClickHandler); } private class OnWordListPreferenceClick implements View.OnClickListener { @Override public void onClick(final View v) { - final Button button = (Button)v.findViewById(R.id.wordlist_button); - animateButton(button, ANIMATION_IN); + // Note : v is the preference view final ViewParent parent = v.getParent(); // Just in case something changed in the framework, test for the concrete class if (!(parent instanceof ListView)) return; final ListView listView = (ListView)parent; - final int myIndex = listView.indexOfChild(v) + listView.getFirstVisiblePosition(); - if (NOT_AN_INDEX != sLastClickedIndex) { - animateButton(getButtonForIndex(listView, sLastClickedIndex), ANIMATION_OUT); + final int indexToOpen; + // Close all first, we'll open back any item that needs to be open. + mInterfaceState.closeAll(); + if (mInterfaceState.isOpen(mWordlistId)) { + // This button being shown. Take note that we don't want to open any button in the + // loop below. + indexToOpen = -1; + } else { + // This button was not being shown. Open it, and remember the index of this + // child as the one to open in the following loop. + mInterfaceState.setOpen(mWordlistId, mStatus); + indexToOpen = listView.indexOfChild(v); + } + final int lastDisplayedIndex = + listView.getLastVisiblePosition() - listView.getFirstVisiblePosition(); + // The "lastDisplayedIndex" is actually displayed, hence the <= + for (int i = 0; i <= lastDisplayedIndex; ++i) { + final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i) + .findViewById(R.id.wordlist_button_switcher); + if (i == indexToOpen) { + buttonSwitcher.animateButton(ButtonSwitcher.ANIMATION_IN); + } else { + buttonSwitcher.animateButton(ButtonSwitcher.ANIMATION_OUT); + } } - sLastClickedIndex = myIndex; - sLastClickedWordlistId = mWordlistId; - } - } - - private Button getButtonForIndex(final ListView listView, final int index) { - final int indexInChildren = index - listView.getFirstVisiblePosition(); - if (indexInChildren < 0 || index > listView.getLastVisiblePosition()) { - // The view is offscreen. - return null; - } - return (Button)listView.getChildAt(indexInChildren).findViewById(R.id.wordlist_button); - } - - private void animateButton(final Button button, final int direction) { - if (null == button) return; - final float outerX = ((View)button.getParent()).getWidth(); - final float innerX = button.getX() - button.getTranslationX(); - if (View.INVISIBLE == button.getVisibility()) { - button.setTranslationX(outerX - innerX); - button.setVisibility(View.VISIBLE); - } - if (ANIMATION_IN == direction) { - button.animate().translationX(0); - } else { - button.animate().translationX(outerX - innerX); } } diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index f77a92885..838863c71 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -34,6 +34,9 @@ import java.util.Arrays; */ public final class SettingsValues { private static final String TAG = SettingsValues.class.getSimpleName(); + // "floatNegativeInfinity" is a special marker string for Float.NEGATIVE_INFINITE + // currently used for auto-correction + private static final String FLOAT_NEGATIVE_INFINITY_MARKER_STRING = "floatNegativeInfinity"; // From resources: public final int mDelayUpdateOldSuggestions; @@ -266,8 +269,12 @@ public final class SettingsValues { try { final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { - autoCorrectionThreshold = Float.parseFloat( - autoCorrectionThresholdValues[arrayIndex]); + final String val = autoCorrectionThresholdValues[arrayIndex]; + if (FLOAT_NEGATIVE_INFINITY_MARKER_STRING.equals(val)) { + autoCorrectionThreshold = Float.NEGATIVE_INFINITY; + } else { + autoCorrectionThreshold = Float.parseFloat(val); + } } } catch (NumberFormatException e) { // Whenever the threshold settings are correct, never come here. @@ -275,7 +282,7 @@ public final class SettingsValues { Log.w(TAG, "Cannot load auto correction threshold setting." + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting + ", autoCorrectionThresholdValues: " - + Arrays.toString(autoCorrectionThresholdValues)); + + Arrays.toString(autoCorrectionThresholdValues), e); } return autoCorrectionThreshold; } diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java index a7a41719e..578787dac 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java @@ -40,18 +40,19 @@ import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.SettingsActivity; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; -import java.util.HashMap; +import java.util.ArrayList; // TODO: Use Fragment to implement welcome screen and setup steps. public final class SetupActivity extends Activity implements View.OnClickListener { private View mWelcomeScreen; private View mSetupScreen; - private SetupStepIndicatorView mStepIndicatorView; private Uri mWelcomeVideoUri; private VideoView mWelcomeVideoView; private View mActionStart; + private View mActionNext; + private TextView mStep1Bullet; private TextView mActionFinish; - private final SetupStepGroup mSetupStepGroup = new SetupStepGroup(); + private SetupStepGroup mSetupStepGroup; private static final String STATE_STEP = "step"; private int mStepNumber; private static final int STEP_0 = 0; @@ -129,12 +130,17 @@ public final class SetupActivity extends Activity implements View.OnClickListene final TextView stepsTitle = (TextView)findViewById(R.id.setup_title); stepsTitle.setText(getString(R.string.setup_steps_title, applicationName)); - mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator); + final SetupStepIndicatorView indicatorView = + (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator); + mSetupStepGroup = new SetupStepGroup(indicatorView); - final SetupStep step1 = new SetupStep(applicationName, - (TextView)findViewById(R.id.setup_step1_bullet), findViewById(R.id.setup_step1), + mStep1Bullet = (TextView)findViewById(R.id.setup_step1_bullet); + mStep1Bullet.setOnClickListener(this); + final SetupStep step1 = new SetupStep(STEP_1, applicationName, + mStep1Bullet, findViewById(R.id.setup_step1), R.string.setup_step1_title, R.string.setup_step1_instruction, - R.drawable.ic_setup_step1, R.string.setup_step1_action); + R.string.setup_step1_finished_instruction, R.drawable.ic_setup_step1, + R.string.setup_step1_action); step1.setAction(new Runnable() { @Override public void run() { @@ -142,12 +148,13 @@ public final class SetupActivity extends Activity implements View.OnClickListene mHandler.startPollingImeSettings(); } }); - mSetupStepGroup.addStep(STEP_1, step1); + mSetupStepGroup.addStep(step1); - final SetupStep step2 = new SetupStep(applicationName, + final SetupStep step2 = new SetupStep(STEP_2, applicationName, (TextView)findViewById(R.id.setup_step2_bullet), findViewById(R.id.setup_step2), R.string.setup_step2_title, R.string.setup_step2_instruction, - R.drawable.ic_setup_step2, R.string.setup_step2_action); + 0 /* finishedInstruction */, R.drawable.ic_setup_step2, + R.string.setup_step2_action); step2.setAction(new Runnable() { @Override public void run() { @@ -156,19 +163,20 @@ public final class SetupActivity extends Activity implements View.OnClickListene .showInputMethodPicker(); } }); - mSetupStepGroup.addStep(STEP_2, step2); + mSetupStepGroup.addStep(step2); - final SetupStep step3 = new SetupStep(applicationName, + final SetupStep step3 = new SetupStep(STEP_3, applicationName, (TextView)findViewById(R.id.setup_step3_bullet), findViewById(R.id.setup_step3), R.string.setup_step3_title, R.string.setup_step3_instruction, - R.drawable.ic_setup_step3, R.string.setup_step3_action); + 0 /* finishedInstruction */, R.drawable.ic_setup_step3, + R.string.setup_step3_action); step3.setAction(new Runnable() { @Override public void run() { invokeSubtypeEnablerOfThisIme(); } }); - mSetupStepGroup.addStep(STEP_3, step3); + mSetupStepGroup.addStep(step3); mWelcomeVideoUri = new Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) @@ -185,6 +193,8 @@ public final class SetupActivity extends Activity implements View.OnClickListene mActionStart = findViewById(R.id.setup_start_label); mActionStart.setOnClickListener(this); + mActionNext = findViewById(R.id.setup_next); + mActionNext.setOnClickListener(this); mActionFinish = (TextView)findViewById(R.id.setup_finish); TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish, getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null); @@ -193,15 +203,25 @@ public final class SetupActivity extends Activity implements View.OnClickListene @Override public void onClick(final View v) { - if (v == mActionStart) { - mStepNumber = STEP_1; - updateSetupStepView(); - return; - } if (v == mActionFinish) { finish(); return; } + final int stepState = determineSetupState(); + final int nextStep; + if (v == mActionStart) { + nextStep = STEP_1; + } else if (v == mActionNext) { + nextStep = mStepNumber + 1; + } else if (v == mStep1Bullet && stepState == STEP_2) { + nextStep = STEP_1; + } else { + nextStep = mStepNumber; + } + if (mStepNumber != nextStep) { + mStepNumber = nextStep; + updateSetupStepView(); + } } private void invokeSetupWizardOfThisIme() { @@ -274,10 +294,10 @@ public final class SetupActivity extends Activity implements View.OnClickListene return myImi.getId().equals(currentImeId); } - private int determineSetupStepNumber() { + private int determineSetupState() { mHandler.cancelPollingImeSettings(); if (!isThisImeEnabled(this)) { - return mWasLanguageAndInputSettingsInvoked ? STEP_1 : STEP_0; + return STEP_1; } if (!isThisImeCurrent(this)) { return STEP_2; @@ -285,6 +305,14 @@ public final class SetupActivity extends Activity implements View.OnClickListene return STEP_3; } + private int determineSetupStepNumber() { + final int stepState = determineSetupState(); + if (stepState == STEP_1) { + return mWasLanguageAndInputSettingsInvoked ? STEP_1 : STEP_0; + } + return stepState; + } + @Override protected void onSaveInstanceState(final Bundle outState) { super.onSaveInstanceState(outState); @@ -351,30 +379,27 @@ public final class SetupActivity extends Activity implements View.OnClickListene return; } mWelcomeVideoView.stopPlayback(); - final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView); - mStepIndicatorView.setIndicatorPosition( - getIndicatorPosition(mStepNumber, mSetupStepGroup.getTotalStep(), layoutDirection)); - mSetupStepGroup.enableStep(mStepNumber); + final boolean isStepActionAlreadyDone = mStepNumber < determineSetupState(); + mSetupStepGroup.enableStep(mStepNumber, isStepActionAlreadyDone); + mActionNext.setVisibility(isStepActionAlreadyDone ? View.VISIBLE : View.GONE); mActionFinish.setVisibility((mStepNumber == STEP_3) ? View.VISIBLE : View.GONE); } - private static float getIndicatorPosition(final int step, final int totalStep, - final int layoutDirection) { - final float pos = ((step - STEP_1) * 2 + 1) / (float)(totalStep * 2); - return (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; - } - static final class SetupStep implements View.OnClickListener { + public final int mStepNo; private final View mStepView; private final TextView mBulletView; private final int mActivatedColor; private final int mDeactivatedColor; + private final String mInstruction; + private final String mFinishedInstruction; private final TextView mActionLabel; private Runnable mAction; - public SetupStep(final String applicationName, final TextView bulletView, - final View stepView, final int title, final int instruction, final int actionIcon, - final int actionLabel) { + public SetupStep(final int stepNo, final String applicationName, final TextView bulletView, + final View stepView, final int title, final int instruction, + final int finishedInstruction,final int actionIcon, final int actionLabel) { + mStepNo = stepNo; mStepView = stepView; mBulletView = bulletView; final Resources res = stepView.getResources(); @@ -383,14 +408,10 @@ public final class SetupActivity extends Activity implements View.OnClickListene final TextView titleView = (TextView)mStepView.findViewById(R.id.setup_step_title); titleView.setText(res.getString(title, applicationName)); - - final TextView instructionView = (TextView)mStepView.findViewById( - R.id.setup_step_instruction); - if (instruction == 0) { - instructionView.setVisibility(View.GONE); - } else { - instructionView.setText(res.getString(instruction, applicationName)); - } + mInstruction = (instruction == 0) ? null + : res.getString(instruction, applicationName); + mFinishedInstruction = (finishedInstruction == 0) ? null + : res.getString(finishedInstruction, applicationName); mActionLabel = (TextView)mStepView.findViewById(R.id.setup_step_action_label); mActionLabel.setText(res.getString(actionLabel)); @@ -403,9 +424,13 @@ public final class SetupActivity extends Activity implements View.OnClickListene } } - public void setEnabled(final boolean enabled) { + public void setEnabled(final boolean enabled, final boolean isStepActionAlreadyDone) { mStepView.setVisibility(enabled ? View.VISIBLE : View.GONE); mBulletView.setTextColor(enabled ? mActivatedColor : mDeactivatedColor); + final TextView instructionView = (TextView)mStepView.findViewById( + R.id.setup_step_instruction); + instructionView.setText(isStepActionAlreadyDone ? mFinishedInstruction : mInstruction); + mActionLabel.setVisibility(isStepActionAlreadyDone ? View.GONE : View.VISIBLE); } public void setAction(final Runnable action) { @@ -423,21 +448,22 @@ public final class SetupActivity extends Activity implements View.OnClickListene } static final class SetupStepGroup { - private final HashMap<Integer, SetupStep> mGroup = CollectionUtils.newHashMap(); + private final SetupStepIndicatorView mIndicatorView; + private final ArrayList<SetupStep> mGroup = CollectionUtils.newArrayList(); - public void addStep(final int stepNo, final SetupStep step) { - mGroup.put(stepNo, step); + public SetupStepGroup(final SetupStepIndicatorView indicatorView) { + mIndicatorView = indicatorView; } - public void enableStep(final int enableStepNo) { - for (final Integer stepNo : mGroup.keySet()) { - final SetupStep step = mGroup.get(stepNo); - step.setEnabled(stepNo == enableStepNo); - } + public void addStep(final SetupStep step) { + mGroup.add(step); } - public int getTotalStep() { - return mGroup.size(); + public void enableStep(final int enableStepNo, final boolean isStepActionAlreadyDone) { + for (final SetupStep step : mGroup) { + step.setEnabled(step.mStepNo == enableStepNo, isStepActionAlreadyDone); + } + mIndicatorView.setIndicatorPosition(enableStepNo - STEP_1, mGroup.size()); } } } diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java index 077a21793..c909507c6 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java @@ -23,6 +23,7 @@ import android.graphics.Path; import android.util.AttributeSet; import android.view.View; +import com.android.inputmethod.compat.ViewCompatUtils; import com.android.inputmethod.latin.R; public final class SetupStepIndicatorView extends View { @@ -36,8 +37,13 @@ public final class SetupStepIndicatorView extends View { mIndicatorPaint.setStyle(Paint.Style.FILL); } - public void setIndicatorPosition(final float xRatio) { - mXRatio = xRatio; + public void setIndicatorPosition(final int stepPos, final int totalStepNum) { + final int layoutDirection = ViewCompatUtils.getLayoutDirection(this); + // The indicator position is the center of the partition that is equally divided into + // the total step number. + final float partionWidth = 1.0f / totalStepNum; + final float pos = stepPos * partionWidth + partionWidth / 2.0f; + mXRatio = (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; invalidate(); } |