Add preliminary setup wizard

Bug: 8159728
Change-Id: I30d9cd637fb1d2e64588550e0aa4387bc1f7e6e5
main
Tadashi G. Takaoka 2013-02-14 16:46:39 +09:00
parent 7739190083
commit 46878544ec
15 changed files with 746 additions and 6 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/setup_step_title"
style="@style/setupStepTitleStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="24dp"
android:paddingRight="24dp" />
<TextView
android:id="@+id/setup_step_instruction"
style="@style/setupStepInstructionStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
android:paddingLeft="24dp"
android:paddingRight="24dp" />
<View
android:layout_width="match_parent"
android:layout_height="2dp" />
<TextView
android:id="@+id/setup_step_action_label"
style="@style/setupStepActionLabelStyle"
android:gravity="center_vertical"
android:drawablePadding="12dp"
android:layout_width="match_parent"
android:layout_height="48dp"
android:clickable="true"
android:focusable="true"
android:paddingLeft="12dp"
android:paddingStart="12dp"
android:paddingRight="24dp"
android:paddingEnd="24dp" />
</LinearLayout>

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.
*/
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/setup_background"
android:paddingLeft="@dimen/setup_horizontal_padding"
android:paddingRight="@dimen/setup_horizontal_padding"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView
android:id="@+id/setup_title"
style="@style/setupTitleStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<LinearLayout
android:id="@+id/setup_step_bullets"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/setup_title"
android:paddingTop="16dp"
android:orientation="horizontal">
<TextView
style="@style/setupStepBulletStyle"
android:text="@string/setup_step1_bullet" />
<TextView
style="@style/setupStepBulletStyle"
android:text="@string/setup_step2_bullet" />
<TextView
style="@style/setupStepBulletStyle"
android:text="@string/setup_step3_bullet" />
</LinearLayout>
<com.android.inputmethod.latin.setup.SetupStepIndicatorView
android:id="@+id/setup_step_indicator"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_below="@id/setup_step_bullets" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/setup_step_indicator">
<include
android:id="@+id/setup_step1"
layout="@layout/setup_step" />
<include
android:id="@+id/setup_step2"
layout="@layout/setup_step" />
<include
android:id="@+id/setup_step3"
layout="@layout/setup_step" />
</FrameLayout>
</RelativeLayout>
</ScrollView>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="setup_title_text_size">64sp</dimen>
<dimen name="setup_horizontal_padding">96dp</dimen>
</resources>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="setup_title_text_size">64sp</dimen>
<dimen name="setup_horizontal_padding">192dp</dimen>
</resources>

View File

@ -53,4 +53,9 @@
<color name="spacebar_text_color_ics">#FFC0C0C0</color>
<color name="spacebar_text_shadow_color_ics">#80000000</color>
<color name="typed_word_color_ics">@color/highlight_color_ics</color>
<!-- Color resources for setup wizard and tutorial -->
<color name="setup_background">#FFEBEBEB</color>
<color name="setup_text_dark">#FF707070</color>
<color name="setup_text_action">@android:color/holo_blue_light</color>
<color name="setup_step_background">@android:color/background_light</color>
</resources>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="setup_title_text_size">46sp</dimen>
<dimen name="setup_horizontal_padding">16dp</dimen>
</resources>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="setupTitleStyle">
<item name="android:textColor">@color/setup_text_dark</item>
<item name="android:textSize">@dimen/setup_title_text_size</item>
</style>
<style name="setupStepBulletStyle">
<item name="android:textColor">@color/setup_text_dark</item>
<item name="android:textSize">22sp</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_weight">1.0</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center_horizontal</item>
</style>
<style name="setupStepTitleStyle">
<item name="android:background">@color/setup_step_background</item>
<item name="android:textColor">@color/setup_text_dark</item>
<item name="android:textSize">22sp</item>
</style>
<style name="setupStepInstructionStyle">
<item name="android:background">@color/setup_step_background</item>
<item name="android:textColor">@color/setup_text_dark</item>
<item name="android:textSize">14sp</item>
</style>
<style name="setupStepActionLabelStyle">
<item name="android:background">@color/setup_step_background</item>
<item name="android:textColor">@color/setup_text_action</item>
<item name="android:textSize">18sp</item>
</style>
</resources>

View File

@ -408,4 +408,29 @@
<!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] -->
<string name="button_default">Default</string>
<!-- Title of the setup wizard. [CHAR LIMT=40] -->
<string name="setup_title">"Installing <xliff:g id="application_name">%s</xliff:g>"</string>
<!-- Ordinal number of the 1st step in the setup wizard. [CHAR LIMIT=5] -->
<string name="setup_step1_bullet">1</string>
<!-- Title of the 1st step in the setup wizard. [CHAR LIMIT=64] -->
<string name="setup_step1_title">"Enable <xliff:g id="application_name">%s</xliff:g> in settings."</string>
<!-- Detailed instruction of the 1st step in the setup wizard. [CHAR LIMIT=80] -->
<string name="setup_step1_instruction">"For security, please check \"<xliff:g id="application_name">%s</xliff:g>\""</string>
<!-- Ordinal number of the 2nd step in the setup wizard. [CHAR LIMIT=5] -->
<string name="setup_step2_bullet">2</string>
<!-- Title of the 2nd step in the setup wizard. [CHAR LIMIT=64] -->
<string name="setup_step2_title">"Switch to <xliff:g id="application_name">%s</xliff:g>."</string>
<!-- Detailed instruction of the 2nd step in the setup wizard. [CHAR LIMIT=80] -->
<string name="setup_step2_instruction">"Now that you've enabled <xliff:g id="application_name">%s</xliff:g>, you can switch to it."</string>
<!-- Ordinal number of the 3rd step in the setup wizard. [CHAR LIMIT=5] -->
<string name="setup_step3_bullet">3</string>
<!-- Title of the 3rd step in the setup wizard. [CHAR LIMIT=64] -->
<string name="setup_step3_title">"Congratulations, you're all set!"</string>
<!-- Detailed instruction of the 3rd step in the setup wizard. [CHAR LIMIT=80] -->
<string name="setup_step3_instruction">Configure additional languages</string>
<!-- Title of the Language & input settings. This should be aligned with msgid="5292716747264442359" -->
<string name="language_settings">Language &amp; input</string>
<!-- Title of the Input method picker. This should be aligned with msgid="4653387336791222978" -->
<string name="select_input_method">Choose input method</string>
</resources>

View File

@ -0,0 +1,44 @@
/*
* 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.compat;
import android.graphics.drawable.Drawable;
import android.widget.TextView;
import java.lang.reflect.Method;
public final class TextViewCompatUtils {
// Note that TextView.setCompoundDrawablesRelative(Drawable,Drawable,Drawable,Drawable) has
// been introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
private static final Method METHOD_setCompoundDrawablesRelative = CompatUtils.getMethod(
TextView.class, "setCompoundDrawablesRelative",
Drawable.class, Drawable.class, Drawable.class, Drawable.class);
private TextViewCompatUtils() {
// This utility class is not publicly instantiable.
}
public static void setCompoundDrawablesRelative(final TextView textView, final Drawable start,
final Drawable top, final Drawable end, final Drawable bottom) {
if (METHOD_setCompoundDrawablesRelative == null) {
textView.setCompoundDrawables(start, top, end, bottom);
return;
}
CompatUtils.invoke(textView, null, METHOD_setCompoundDrawablesRelative,
start, top, end, bottom);
}
}

View File

@ -0,0 +1,68 @@
/*
* 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.compat;
import android.view.View;
import java.lang.reflect.Method;
public final class ViewCompatUtils {
// Note that View.LAYOUT_DIRECTION_LTR and View.LAYOUT_DIRECTION_RTL have been introduced in
// API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
public static final int LAYOUT_DIRECTION_LTR = (Integer)CompatUtils.getFieldValue(null, 0x0,
CompatUtils.getField(View.class, "LAYOUT_DIRECTION_LTR"));
public static final int LAYOUT_DIRECTION_RTL = (Integer)CompatUtils.getFieldValue(null, 0x1,
CompatUtils.getField(View.class, "LAYOUT_DIRECTION_RTL"));
// Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int), and
// View.getLayoutDirection() have been introduced in API level 17
// (Build.VERSION_CODE.JELLY_BEAN_MR1).
private static final Method METHOD_getPaddingEnd = CompatUtils.getMethod(
View.class, "getPaddingEnd");
private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod(
View.class, "setPaddingRelative",
Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE);
private static final Method METHOD_getLayoutDirection = CompatUtils.getMethod(
View.class, "getLayoutDirection");
private ViewCompatUtils() {
// This utility class is not publicly instantiable.
}
public static int getPaddingEnd(final View view) {
if (METHOD_getPaddingEnd == null) {
return view.getPaddingRight();
}
return (Integer)CompatUtils.invoke(view, 0, METHOD_getPaddingEnd);
}
public static void setPaddingRelative(final View view, final int start, final int top,
final int end, final int bottom) {
if (METHOD_setPaddingRelative == null) {
view.setPadding(start, top, end, bottom);
return;
}
CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom);
}
public static int getLayoutDirection(final View view) {
if (METHOD_getLayoutDirection == null) {
return LAYOUT_DIRECTION_LTR;
}
return (Integer)CompatUtils.invoke(view, 0, METHOD_getLayoutDirection);
}
}

View File

@ -18,22 +18,323 @@ package com.android.inputmethod.latin.setup;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Message;
import android.provider.Settings;
import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import com.android.inputmethod.compat.TextViewCompatUtils;
import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.SettingsActivity;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
import java.util.HashMap;
public final class SetupActivity extends Activity {
private SetupStepIndicatorView mStepIndicatorView;
private final SetupStepGroup mSetupSteps = new SetupStepGroup();
private static final String STATE_STEP = "step";
private int mStepNo;
private static final int STEP_1 = 1;
private static final int STEP_2 = 2;
private static final int STEP_3 = 3;
private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
static final class SettingsPoolingHandler extends StaticInnerHandlerWrapper<SetupActivity> {
private static final int MSG_POLLING_IME_SETTINGS = 0;
private static final long IME_SETTINGS_POLLING_INTERVAL = 200;
public SettingsPoolingHandler(final SetupActivity outerInstance) {
super(outerInstance);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
public void handleMessage(final Message msg) {
final SetupActivity setupActivity = getOuterInstance();
switch (msg.what) {
case MSG_POLLING_IME_SETTINGS:
if (setupActivity.isMyImeEnabled()) {
setupActivity.invokeSetupWizardOfThisIme();
return;
}
startPollingImeSettings();
break;
}
}
public void startPollingImeSettings() {
sendMessageDelayed(obtainMessage(MSG_POLLING_IME_SETTINGS),
IME_SETTINGS_POLLING_INTERVAL);
}
public void cancelPollingImeSettings() {
removeMessages(MSG_POLLING_IME_SETTINGS);
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar);
super.onCreate(savedInstanceState);
// TODO: Implement setup wizard.
setContentView(R.layout.setup_wizard);
RichInputMethodManager.init(this);
if (savedInstanceState == null) {
mStepNo = determineSetupStepNo();
} else {
mStepNo = savedInstanceState.getInt(STATE_STEP);
}
if (mStepNo == STEP_3) {
// This IME already has been enabled and set as current IME.
// TODO: Implement tutorial.
invokeSettingsOfThisIme();
finish();
return;
}
// TODO: Use sans-serif-thin font family depending on the system locale white list and
// the SDK version.
final TextView titleView = (TextView)findViewById(R.id.setup_title);
titleView.setText(getString(R.string.setup_title, getString(R.string.english_ime_name)));
mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
final SetupStep step1 = new SetupStep(findViewById(R.id.setup_step1),
R.string.setup_step1_title, R.string.setup_step1_instruction,
R.drawable.ic_settings_language, R.string.language_settings);
step1.setAction(new Runnable() {
@Override
public void run() {
invokeLanguageAndInputSettings();
mHandler.startPollingImeSettings();
}
});
mSetupSteps.addStep(STEP_1, step1);
final SetupStep step2 = new SetupStep(findViewById(R.id.setup_step2),
R.string.setup_step2_title, R.string.setup_step2_instruction,
0 /* actionIcon */, R.string.select_input_method);
step2.setAction(new Runnable() {
@Override
public void run() {
// Invoke input method picker.
RichInputMethodManager.getInstance().getInputMethodManager()
.showInputMethodPicker();
}
});
mSetupSteps.addStep(STEP_2, step2);
final SetupStep step3 = new SetupStep(findViewById(R.id.setup_step3),
R.string.setup_step3_title, 0 /* instruction */,
R.drawable.sym_keyboard_language_switch, R.string.setup_step3_instruction);
step3.setAction(new Runnable() {
@Override
public void run() {
invokeSubtypeEnablerOfThisIme();
}
});
mSetupSteps.addStep(STEP_3, step3);
}
private void invokeSetupWizardOfThisIme() {
final Intent intent = new Intent();
intent.setClass(this, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
intent.setClass(this, SetupActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
private void invokeSettingsOfThisIme() {
final Intent intent = new Intent();
intent.setClass(this, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
private void invokeLanguageAndInputSettings() {
final Intent intent = new Intent();
intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
}
private void invokeSubtypeEnablerOfThisIme() {
final InputMethodInfo imi =
RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
final Intent intent = new Intent();
intent.setAction(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imi.getId());
startActivity(intent);
}
private boolean isMyImeEnabled() {
final String packageName = getPackageName();
final InputMethodManager imm = RichInputMethodManager.getInstance().getInputMethodManager();
for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) {
if (packageName.equals(imi.getPackageName())) {
return true;
}
}
return false;
}
private boolean isMyImeCurrent() {
final InputMethodInfo myImi =
RichInputMethodManager.getInstance().getInputMethodInfoOfThisIme();
final String currentImeId = Settings.Secure.getString(
getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
return myImi.getId().equals(currentImeId);
}
private int determineSetupStepNo() {
mHandler.cancelPollingImeSettings();
if (!isMyImeEnabled()) {
return STEP_1;
}
if (!isMyImeCurrent()) {
return STEP_2;
}
return STEP_3;
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_STEP, mStepNo);
}
@Override
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mStepNo = savedInstanceState.getInt(STATE_STEP);
}
@Override
protected void onStart() {
super.onStart();
mStepNo = determineSetupStepNo();
}
@Override
protected void onRestart() {
super.onRestart();
mStepNo = determineSetupStepNo();
}
@Override
protected void onResume() {
super.onResume();
updateSetupStepView();
}
@Override
public void onWindowFocusChanged(final boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
return;
}
mStepNo = determineSetupStepNo();
updateSetupStepView();
}
private void updateSetupStepView() {
final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView);
mStepIndicatorView.setIndicatorPosition(
getIndicatorPosition(mStepNo, mSetupSteps.getTotalStep(), layoutDirection));
mSetupSteps.enableStep(mStepNo);
}
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 {
private final View mRootView;
private final TextView mActionLabel;
private Runnable mAction;
public SetupStep(final View rootView, final int title, final int instruction,
final int actionIcon, final int actionLabel) {
mRootView = rootView;
final Resources res = rootView.getResources();
final String applicationName = res.getString(R.string.english_ime_name);
final TextView titleView = (TextView)rootView.findViewById(R.id.setup_step_title);
titleView.setText(res.getString(title, applicationName));
final TextView instructionView = (TextView)rootView.findViewById(
R.id.setup_step_instruction);
if (instruction == 0) {
instructionView.setVisibility(View.GONE);
} else {
instructionView.setText(res.getString(instruction, applicationName));
}
mActionLabel = (TextView)rootView.findViewById(R.id.setup_step_action_label);
mActionLabel.setText(res.getString(actionLabel));
if (actionIcon == 0) {
final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel);
ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0);
} else {
final int overrideColor = res.getColor(R.color.setup_text_action);
final Drawable icon = res.getDrawable(actionIcon);
icon.setColorFilter(overrideColor, PorterDuff.Mode.MULTIPLY);
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
TextViewCompatUtils.setCompoundDrawablesRelative(
mActionLabel, icon, null, null, null);
}
}
public void setEnabled(final boolean enabled) {
mRootView.setVisibility(enabled ? View.VISIBLE : View.GONE);
}
public void setAction(final Runnable action) {
mActionLabel.setOnClickListener(this);
mAction = action;
}
@Override
public void onClick(final View v) {
if (mAction != null) {
mAction.run();
}
}
}
static final class SetupStepGroup {
private final HashMap<Integer, SetupStep> mGroup = CollectionUtils.newHashMap();
public void addStep(final int stepNo, final SetupStep step) {
mGroup.put(stepNo, step);
}
public void enableStep(final int enableStepNo) {
for (final Integer stepNo : mGroup.keySet()) {
final SetupStep step = mGroup.get(stepNo);
step.setEnabled(stepNo == enableStepNo);
}
}
public int getTotalStep() {
return mGroup.size();
}
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.latin.setup;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import com.android.inputmethod.latin.R;
public final class SetupStepIndicatorView extends View {
private final Path mIndicatorPath = new Path();
private final Paint mIndicatorPaint = new Paint();
private float mXRatio;
public SetupStepIndicatorView(final Context context, final AttributeSet attrs) {
super(context, attrs);
mIndicatorPaint.setColor(getResources().getColor(R.color.setup_step_background));
mIndicatorPaint.setStyle(Paint.Style.FILL);
}
public void setIndicatorPosition(final float xRatio) {
mXRatio = xRatio;
invalidate();
}
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
final int xPos = (int)(getWidth() * mXRatio);
final int height = getHeight();
mIndicatorPath.rewind();
mIndicatorPath.moveTo(xPos, 0);
mIndicatorPath.lineTo(xPos + height, height);
mIndicatorPath.lineTo(xPos - height, height);
mIndicatorPath.close();
canvas.drawPath(mIndicatorPath, mIndicatorPaint);
}
}