Add welcome screen to setup wizard

This is a preliminary implementation because the welcome screen video
is just a placeholder.

Bug: 8159728
Change-Id: I6a2459a266babec2f078fc393b18c77b0b7992a8
This commit is contained in:
Tadashi G. Takaoka 2013-04-18 17:19:40 +09:00
parent fcefabf9ab
commit 68e4de1e78
7 changed files with 265 additions and 2 deletions

View file

@ -0,0 +1,27 @@
<?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="match_parent"
android:orientation="vertical">
<include layout="@layout/setup_welcome_title" />
<include layout="@layout/setup_welcome_video" />
</LinearLayout>

View file

@ -0,0 +1,32 @@
<?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.
*/
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/setup_welcome_title"
style="@style/setupTitleStyle"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="@+id/setup_welcome_description"
android:text="@string/setup_welcome_additional_description"
android:layout_marginTop="12dp"
style="@style/setupWelcomeDescritpionStyle" />
</merge>

View file

@ -0,0 +1,31 @@
<?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.
*/
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<VideoView
android:id="@+id/setup_welcome_video"
android:layout_margin="36dp"
android:layout_width="240dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true" />
<com.android.inputmethod.latin.setup.SetupStartIndicatorView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</merge>

View file

@ -26,6 +26,9 @@
android:paddingRight="@dimen/setup_horizontal_padding"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<include
android:id="@+id/setup_welcome_screen"
layout="@layout/setup_welcome_screen" />
<include
android:id="@+id/setup_steps_screen"
layout="@layout/setup_steps_screen" />

Binary file not shown.

View file

@ -17,9 +17,12 @@
package com.android.inputmethod.latin.setup;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.provider.Settings;
@ -27,6 +30,7 @@ import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.VideoView;
import com.android.inputmethod.compat.TextViewCompatUtils;
import com.android.inputmethod.compat.ViewCompatUtils;
@ -40,14 +44,21 @@ import java.util.HashMap;
// 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 TextView mActionFinish;
private final SetupStepGroup mSetupStepGroup = new SetupStepGroup();
private static final String STATE_STEP = "step";
private int mStepNumber;
private static final int STEP_0 = 0;
private static final int STEP_1 = 1;
private static final int STEP_2 = 2;
private static final int STEP_3 = 3;
private boolean mWasLanguageAndInputSettingsInvoked;
private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
@ -109,8 +120,13 @@ public final class SetupActivity extends Activity implements View.OnClickListene
return;
}
final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
final String applicationName = getResources().getString(getApplicationInfo().labelRes);
mWelcomeScreen = findViewById(R.id.setup_welcome_screen);
final TextView welcomeTitle = (TextView)findViewById(R.id.setup_welcome_title);
welcomeTitle.setText(getString(R.string.setup_welcome_title, applicationName));
mSetupScreen = findViewById(R.id.setup_steps_screen);
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);
@ -154,6 +170,21 @@ public final class SetupActivity extends Activity implements View.OnClickListene
});
mSetupStepGroup.addStep(STEP_3, step3);
mWelcomeVideoUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(getPackageName())
.path(Integer.toString(R.raw.setup_welcome_video))
.build();
mWelcomeVideoView = (VideoView)findViewById(R.id.setup_welcome_video);
mWelcomeVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(final MediaPlayer mp) {
mp.start();
}
});
mActionStart = findViewById(R.id.setup_start_label);
mActionStart.setOnClickListener(this);
mActionFinish = (TextView)findViewById(R.id.setup_finish);
TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish,
getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null);
@ -162,6 +193,11 @@ 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;
@ -190,6 +226,7 @@ public final class SetupActivity extends Activity implements View.OnClickListene
intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
mWasLanguageAndInputSettingsInvoked = true;
}
private void invokeSubtypeEnablerOfThisIme() {
@ -240,7 +277,7 @@ public final class SetupActivity extends Activity implements View.OnClickListene
private int determineSetupStepNumber() {
mHandler.cancelPollingImeSettings();
if (!isThisImeEnabled(this)) {
return STEP_1;
return mWasLanguageAndInputSettingsInvoked ? STEP_1 : STEP_0;
}
if (!isThisImeCurrent(this)) {
return STEP_2;
@ -278,6 +315,22 @@ public final class SetupActivity extends Activity implements View.OnClickListene
updateSetupStepView();
}
@Override
public void onBackPressed() {
if (mStepNumber == STEP_1) {
mStepNumber = STEP_0;
updateSetupStepView();
return;
}
super.onBackPressed();
}
@Override
protected void onPause() {
mWelcomeVideoView.stopPlayback();
super.onPause();
}
@Override
public void onWindowFocusChanged(final boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
@ -289,6 +342,15 @@ public final class SetupActivity extends Activity implements View.OnClickListene
}
private void updateSetupStepView() {
final boolean welcomeScreen = (mStepNumber == STEP_0);
mWelcomeScreen.setVisibility(welcomeScreen ? View.VISIBLE : View.GONE);
mSetupScreen.setVisibility(welcomeScreen ? View.GONE: View.VISIBLE);
if (welcomeScreen) {
mWelcomeVideoView.setVideoURI(mWelcomeVideoUri);
mWelcomeVideoView.start();
return;
}
mWelcomeVideoView.stopPlayback();
final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView);
mStepIndicatorView.setIndicatorPosition(
getIndicatorPosition(mStepNumber, mSetupStepGroup.getTotalStep(), layoutDirection));

View file

@ -0,0 +1,108 @@
/*
* 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.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
public final class SetupStartIndicatorView extends LinearLayout {
public SetupStartIndicatorView(final Context context, final AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
LayoutInflater.from(context).inflate(R.layout.setup_start_indicator_label, this);
final LabelView labelView = (LabelView)findViewById(R.id.setup_start_label);
labelView.setIndicatorView(findViewById(R.id.setup_start_indicator));
}
public static final class LabelView extends TextView {
private View mIndicatorView;
public LabelView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public void setIndicatorView(final View indicatorView) {
mIndicatorView = indicatorView;
}
@Override
public void setPressed(final boolean pressed) {
super.setPressed(pressed);
if (mIndicatorView != null) {
mIndicatorView.setPressed(pressed);
}
}
}
public static final class IndicatorView extends View {
private final Path mIndicatorPath = new Path();
private final Paint mIndicatorPaint = new Paint();
private final ColorStateList mIndicatorColor;
public IndicatorView(final Context context, final AttributeSet attrs) {
super(context, attrs);
mIndicatorColor = getResources().getColorStateList(
R.color.setup_step_action_background);
mIndicatorPaint.setStyle(Paint.Style.FILL);
}
@Override
public void setPressed(final boolean pressed) {
super.setPressed(pressed);
invalidate();
}
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
final int layoutDirection = ViewCompatUtils.getLayoutDirection(this);
final int width = getWidth();
final int height = getHeight();
final float halfHeight = height / 2.0f;
final Path path = mIndicatorPath;
path.rewind();
if (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) {
// Left arrow
path.moveTo(width, 0.0f);
path.lineTo(0.0f, halfHeight);
path.lineTo(width, height);
} else { // LAYOUT_DIRECTION_LTR
// Right arrow
path.moveTo(0.0f, 0.0f);
path.lineTo(width, halfHeight);
path.lineTo(0.0f, height);
}
path.close();
final int[] stateSet = getDrawableState();
final int color = mIndicatorColor.getColorForState(stateSet, 0);
mIndicatorPaint.setColor(color);
canvas.drawPath(path, mIndicatorPaint);
}
}
}