First pass of XL account setup

* AccountSetupBasics now has an XL version
* This is from prelim wireframes
* Final colors, text size, and positioning all TBD
* Fixed a StrictMode violation (counting #accounts in onCreate)
* Lightweight (non-shippable) fixes for functional phone UX

Bug: 3188940
Change-Id: Idf6cb514208eba07eaa20b20abfd5fcc3dae1751
This commit is contained in:
Andy Stadler 2010-11-14 21:16:49 -08:00
parent 949138d482
commit 7988164ddf
11 changed files with 395 additions and 81 deletions

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<!-- Large-screen holder - landscape - see layout/ for small-screen version -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="16dip"
android:paddingLeft="96dip"
android:paddingRight="96dip"
>
<!-- Headline and hairline divider -->
<TextView
android:id="@+id/headline"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="16dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account_setup_basics_headline"
android:textAppearance="@style/accountSetupHeadline" />
<View
android:id="@+id/top_divider"
android:layout_below="@+id/headline"
android:layout_marginBottom="16dip"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/account_setup_divider_color" />
<!-- Buttons on the right -->
<Button
android:id="@+id/manual_setup"
android:layout_below="@+id/top_divider"
android:layout_alignParentRight="true"
android:layout_marginTop="32dip"
android:layout_marginRight="16dip"
style="@style/accountSetupButton"
android:text="@string/account_setup_basics_manual_setup_action" />
<Button
android:id="@+id/next"
android:layout_below="@+id/manual_setup"
android:layout_alignParentRight="true"
android:layout_marginTop="32dip"
android:layout_marginRight="16dip"
style="@style/accountSetupButton"
android:text="@string/next_action" />
<!-- Fragment on the left containing the setup info -->
<fragment
android:id="@+id/setup_basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_below="@+id/top_divider"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/manual_setup"
android:layout_marginRight="64dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<!-- Large-screen holder - portrait - see layout/ for small-screen version -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="64dip"
android:paddingLeft="96dip"
android:paddingRight="96dip"
>
<!-- Headline and hairline divider -->
<TextView
android:id="@+id/headline"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="16dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account_setup_basics_headline"
android:textAppearance="@style/accountSetupHeadline" />
<View
android:id="@+id/top_divider"
android:layout_below="@+id/headline"
android:layout_marginBottom="32dip"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/account_setup_divider_color" />
<!-- Fragment in the middle containing the setup info -->
<fragment
android:id="@+id/setup_basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_below="@+id/top_divider"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<!-- Buttons below -->
<Button
android:id="@+id/manual_setup"
android:layout_below="@+id/setup_basics_fragment"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dip"
style="@style/accountSetupButton"
android:text="@string/account_setup_basics_manual_setup_action" />
<Button
android:id="@+id/next"
android:layout_below="@+id/manual_setup"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dip"
style="@style/accountSetupButton"
android:text="@string/next_action" />
</RelativeLayout>

View File

@ -14,16 +14,45 @@
limitations under the License.
-->
<!-- Small-screen holder - see layout-xlarge for large-screen version -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<fragment
android:id="@+id/setup_basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
android:layout_height="match_parent"
>
<!-- Fragment in the middle containing the setup info -->
<fragment
android:id="@+id/setup_basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_below="@+id/top_divider"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<!-- Buttons below -->
<Button
android:id="@+id/manual_setup"
android:layout_below="@+id/setup_basics_fragment"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dip"
style="@style/accountSetupButton"
android:text="@string/account_setup_basics_manual_setup_action" />
<Button
android:id="@+id/next"
android:layout_below="@+id/manual_setup"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dip"
style="@style/accountSetupButton"
android:text="@string/next_action" />
</RelativeLayout>
</ScrollView>

View File

@ -14,46 +14,89 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<!-- Common data-entry area of initial account setup screen - email, password, default check -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
android:layout_height="wrap_content" >
<TextView
android:id="@+id/instructions"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:layout_marginTop="16dip"
android:layout_marginLeft="16dip"
android:textSize="20sp"
android:text="@string/accounts_welcome"
android:textColor="?android:attr/textColorPrimary" />
<TableLayout
android:id="@+id/email_password_table"
android:layout_below="@+id/instructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dip"
android:layout_marginLeft="16dip"
android:stretchColumns="1" >
<TableRow
android:paddingTop="16dip" >
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginRight="16dip"
android:text="@string/account_setup_basics_email_label"
android:textColor="?android:attr/textColorPrimary" />
<EditText
android:id="@+id/account_email"
android:layout_marginRight="96dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:imeOptions="actionNext" />
</TableRow>
<TableRow
android:paddingTop="16dip" >
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginRight="16dip"
android:text="@string/account_setup_basics_password_label"
android:textColor="?android:attr/textColorPrimary" />
<EditText
android:id="@+id/account_password"
android:layout_marginRight="96dip"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:inputType="textPassword"
android:imeOptions="actionDone"
android:nextFocusDown="@+id/next" />
</TableRow>
</TableLayout>
<!-- Note, the next three items should be shown/hidden as a group -->
<View
android:id="@+id/account_default_divider_1"
android:layout_below="@+id/email_password_table"
android:layout_marginTop="48dip"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<EditText
android:id="@+id/account_email"
android:hint="@string/account_setup_basics_email_hint"
android:inputType="textEmailAddress"
android:imeOptions="actionNext"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
<EditText
android:id="@+id/account_password"
android:hint="@string/account_setup_basics_password_hint"
android:inputType="textPassword"
android:imeOptions="actionDone"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:nextFocusDown="@+id/next" />
android:layout_height="1px"
android:background="@color/account_setup_divider_color"
android:visibility="gone" />
<CheckBox
android:id="@+id/account_default"
android:layout_below="@+id/account_default_divider_1"
android:layout_marginTop="16dip"
android:layout_marginBottom="16dip"
android:layout_marginLeft="32dip"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:text="@string/account_setup_basics_default_label"
android:visibility="gone" />
<View
android:id="@+id/account_default_divider_2"
android:layout_below="@+id/account_default"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
android:layout_height="1px"
android:background="@color/account_setup_divider_color"
android:visibility="gone" />
</RelativeLayout>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<!-- STOPSHIP need final colors for all of account_setup_* -->
<!-- Specializations for xlarge screens - most colors are in values/colors.xml -->
<resources>
<!-- Account setup screens -->
<color name="account_setup_title_color">#FFA6C839</color>
<color name="account_setup_divider_color">#b6d650</color>
</resources>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<!-- STOPSHIP need final styles for all of account_setup_* -->
<!-- Specializations for xlarge screens - most colors are in values/colors.xml -->
<resources>
<!-- The large headline at the top of every account setup screen -->
<style name="accountSetupHeadline">
<item name="android:textSize">28sp</item>
<item name="android:textColor">@color/account_setup_headline_color</item>
</style>
<!-- Wizard buttons on the account setup screens -->
<style name="accountSetupButton">
<item name="android:layout_width">240sp</item>
<item name="android:layout_height">70sp</item>
<item name="android:textSize">24sp</item>
</style>
</resources>

View File

@ -14,7 +14,14 @@
limitations under the License.
-->
<!-- STOPSHIP need final colors for all of account_setup_* -->
<!-- See also values-xlarge for specializations for xlarge screens -->
<resources>
<!-- Account setup screens -->
<color name="account_setup_headline_color">#FFA6C839</color>
<color name="account_setup_divider_color">#b6d650</color>
<!-- Main UI -->
<color name="message_list_item_background_unread">#404040</color>
<color name="message_list_item_background_read">#000000</color>
<color name="account_folder_list_item_separator">#303030</color>

View File

@ -19,6 +19,10 @@
<!-- Deprecated strings - Move the identifiers to this section, mark as DO NOT TRANSLATE,
and remove the actual text. These will be removed in a bulk operation. -->
<!-- Do Not Translate. Unused string. -->
<string name="account_setup_basics_email_hint" translatable="false"></string>
<!-- Do Not Translate. Unused string. -->
<string name="account_setup_basics_password_hint" translatable="false"></string>
<!-- Do Not Translate. Unused string. -->
<string name="account_settings_exchange_summary" translatable="false"></string>
<!-- Do Not Translate. Unused string. -->
<string name="message_compose_attachments_skipped_toast" translatable="false"></string>
@ -449,13 +453,15 @@ save attachment.</string>
%1$s</xliff:g> - <xliff:g id="text" example="Hi, John. Blah...">%2$s</xliff:g></string>
<!-- Title of screen when setting up new email account -->
<string name="account_setup_basics_title">Set up email</string>
<string name="account_setup_basics_title">Account setup</string>
<!-- Title of the screen when adding exchange account -->
<string name="account_setup_basics_exchange_title">
Add an Exchange account</string>
<!-- Title of the screen when adding exchange account -->
<string name="account_setup_basics_exchange_title_alternate">
Add an Exchange ActiveSync account</string>
<!-- Headline of screen when setting up new email account (large text over divider) -->
<string name="account_setup_basics_headline">Email account</string>
<!-- On "Set up email" screen, enthusiastic welcome message. -->
<string name="accounts_welcome">You can configure Email for most accounts in just a few steps.
</string>
@ -466,16 +472,19 @@ save attachment.</string>
<string name="accounts_welcome_exchange_alternate">
You can configure an Exchange ActiveSync account in just a few steps.</string>
<!-- On "Set up email" screen, hint for account email address text field -->
<string name="account_setup_basics_email_hint">Email address</string>
<string name="account_setup_basics_email_label">Email address</string>
<!-- On "Set up email" screen, hint for account email password text field -->
<string name="account_setup_basics_password_hint">Password</string>
<!-- On "Set up email" screen, checkbox label for making this the new account be the default account -->
<string name="account_setup_basics_default_label">Send email from this account by default.</string>
<string name="account_setup_basics_password_label">Password</string>
<!-- On "Set up email" screen, checkbox label for making the new account the default account -->
<string name="account_setup_basics_default_label">
Send email from this account by default.</string>
<!-- Button name on "Set up email" screen -->
<string name="account_setup_basics_manual_setup_action">Manual setup</string>
<!-- Toast when we can't build a URI from the given email & password -->
<!-- Note, the error message in the toast is purposefully vague, because I *don't* know exactly what's wrong. -->
<string name="account_setup_username_password_toast">Please type a valid email address and password.</string>
<!-- Note, the error message in the toast is purposefully vague, because I *don't* know
exactly what's wrong. -->
<string name="account_setup_username_password_toast">
Please type a valid email address and password.</string>
<!-- Title of dialog shown when a duplicate account is created -->
<string name="account_duplicate_dlg_title">Duplicate Account</string>
<!-- Message of dialog shown when a duplicate account is created. The display name of

View File

@ -14,6 +14,7 @@
limitations under the License.
-->
<!-- See also values-xlarge for specializations for xlarge screens -->
<resources>
<style name="unreadCount">
<item name="android:ellipsize">end</item>
@ -33,4 +34,18 @@
<item name="android:windowContentOverlay">@null</item>
</style>
<!-- The large headline at the top of every account setup screen -->
<!-- STOPSHIP copied from xlarge - do something for phone UX -->
<style name="accountSetupHeadline">
<item name="android:textSize">22sp</item>
<item name="android:textColor">@color/account_setup_headline_color</item>
</style>
<!-- Wizard buttons on the account setup screens -->
<!-- TODO these are estimates based on TBD phone UX -->
<style name="accountSetupButton">
<item name="android:layout_width">160sp</item>
<item name="android:layout_height">40sp</item>
<item name="android:textAppearance">?android:attr/textColorPrimary</item>
</style>
</resources>

View File

@ -31,8 +31,9 @@ import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* Prompts the user for the email address and password. Also prompts for "Use this account as
@ -45,11 +46,14 @@ import android.view.MenuItem;
* AccountSetupAccountType activity where the user can begin to manually configure the account.
*/
public class AccountSetupBasics extends AccountSetupActivity
implements AccountSetupBasicsFragment.Callback, AccountCheckSettingsFragment.Callbacks {
implements AccountSetupBasicsFragment.Callback, AccountCheckSettingsFragment.Callbacks,
OnClickListener {
private AccountSetupBasicsFragment mFragment;
private boolean mManualButtonDisplayed;
private boolean mNextButtonEnabled;
private Button mManualButton;
private Button mNextButton;
// Used when this Activity is called as part of account authentification flow,
// which requires to do extra work before and after the account creation.
@ -127,7 +131,6 @@ public class AccountSetupBasics extends AccountSetupActivity
mFragment = (AccountSetupBasicsFragment)
getFragmentManager().findFragmentById(R.id.setup_basics_fragment);
mManualButtonDisplayed = true;
boolean alternateStrings = false;
if (flowMode == SetupData.FLOW_MODE_ACCOUNT_MANAGER_EAS) {
@ -143,6 +146,16 @@ public class AccountSetupBasics extends AccountSetupActivity
// Configure fragment
mFragment.setCallback(this, alternateStrings);
// Configure buttons
mManualButton = (Button) findViewById(R.id.manual_setup);
mNextButton = (Button) findViewById(R.id.next);
mManualButton.setVisibility(mManualButtonDisplayed ? View.VISIBLE : View.INVISIBLE);
mManualButton.setOnClickListener(this);
mNextButton.setOnClickListener(this);
// Force disabled until fragment notifies otherwise
mNextButtonEnabled = true;
this.onEnableProceedButtons(false);
mAccountAuthenticatorResponse =
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
@ -193,44 +206,19 @@ public class AccountSetupBasics extends AccountSetupActivity
}
/**
* Add "Next" & "Manual" buttons when this activity is displayed
* Implements OnClickListener
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
int menuId = mManualButtonDisplayed
? R.menu.account_setup_manual_next_option
: R.menu.account_setup_next_option;
getMenuInflater().inflate(menuId, menu);
return super.onCreateOptionsMenu(menu);
}
/**
* Enable/disable "Next" & "Manual" buttons
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.next).setEnabled(mNextButtonEnabled);
if (mManualButtonDisplayed) {
menu.findItem(R.id.manual_setup).setEnabled(mNextButtonEnabled);
}
return super.onPrepareOptionsMenu(menu);
}
/**
* Respond to clicks in the "Next" button
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
public void onClick(View v) {
switch (v.getId()) {
case R.id.next:
mFragment.onNext();
return true;
break;
case R.id.manual_setup:
// no AutoDiscover - user clicked "manual"
mFragment.onManualSetup(false);
return true;
break;
}
return super.onOptionsItemSelected(item);
}
/**
@ -242,7 +230,8 @@ public class AccountSetupBasics extends AccountSetupActivity
mNextButtonEnabled = enabled;
if (enabled != wasEnabled) {
invalidateOptionsMenu();
mManualButton.setEnabled(enabled);
mNextButton.setEnabled(enabled);
}
}

View File

@ -31,6 +31,7 @@ import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
@ -55,6 +56,7 @@ import java.net.URISyntaxException;
* AccountSetupAccountType activity.
*
* TODO: Move provider lookups to AsyncTask(s)
* TODO: Confirm not broken on Phone UX
*/
public class AccountSetupBasicsFragment extends Fragment implements TextWatcher {
private final static boolean ENTER_DEBUG_SCREEN = true;
@ -130,13 +132,9 @@ public class AccountSetupBasicsFragment extends Fragment implements TextWatcher
mEmailView.addTextChangedListener(this);
mPasswordView.addTextChangedListener(this);
// TODO move this to an AsyncTask
// Find out how many accounts we have, and if there one or more, then we have a choice
// about being default or not.
int numAccounts = EmailContent.count(getActivity(), EmailContent.Account.CONTENT_URI);
if (numAccounts > 0) {
mDefaultView.setVisibility(View.VISIBLE);
}
// If there are one or more accounts already in existence, then display
// the "use as default" checkbox (it defaults to hidden).
new DisplayCheckboxTask().execute();
return view;
}
@ -300,6 +298,28 @@ public class AccountSetupBasicsFragment extends Fragment implements TextWatcher
return name;
}
/**
* AsyncTask checks count of accounts and displays "use this account as default" checkbox
* if there are more than one.
*/
private class DisplayCheckboxTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... params) {
return EmailContent.count(getActivity(), EmailContent.Account.CONTENT_URI);
}
@Override
protected void onPostExecute(Integer numAccounts) {
if (numAccounts > 0) {
View container = AccountSetupBasicsFragment.this.getView();
container.findViewById(R.id.account_default_divider_1).setVisibility(View.VISIBLE);
mDefaultView.setVisibility(View.VISIBLE);
container.findViewById(R.id.account_default_divider_2).setVisibility(View.VISIBLE);
}
}
}
/**
* Finish the auto setup process, in some cases after showing a warning dialog.
*/