New account spinner
- Don't use the action bar spinner. Instead use a custom view to show the current account. (It's not a spinner; now we show the dropdown list by ourselves, which gives us more detailed control.) - Also show the current mailbox name/unread count with the account name. - Removed the mailbox info loader in ABC. Instead, now the AccountSelectorAdapter loader loads the current account/mailbox name, and the unread count as extras. - Now ABC.Callback.onMailboxSelected passed an account ID as well as a mailbox ID. - There's new code paths that can cause the "fragment transaction in onLoadFinished" exception. We need to fix this properly, but for now we just use commitAllowingStateLoss(). Bug 4948352 Change-Id: I73bb8b7530f8328ca1c86382ac0a54086ad061d7
This commit is contained in:
parent
ad6c48b2d3
commit
4689cb7100
|
@ -1,30 +0,0 @@
|
||||||
<?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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
TextView for the collapsed account spinner.
|
|
||||||
TODO: Need to widen maxWidth dynamically when the mailbox name isn't shown
|
|
||||||
on the action bar.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/display_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:maxWidth="@dimen/action_bar_account_name_max_width"
|
|
||||||
style="@style/action_bar_account_name"
|
|
||||||
/>
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginLeft="@dimen/action_bar_mailbox_name_left_margin"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/mailbox_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:maxWidth="@dimen/action_bar_mailbox_name_max_width"
|
|
||||||
android:textSize="18dp"
|
|
||||||
android:textColor="@color/text_ternary_color"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:gravity="left|center"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/unread_count"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
style="@style/action_bar_unread_count"
|
|
||||||
android:gravity="center"
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
|
|
@ -26,8 +26,8 @@
|
||||||
android:layout_height="0dip"
|
android:layout_height="0dip"
|
||||||
>
|
>
|
||||||
<include
|
<include
|
||||||
android:id="@+id/current_mailbox_container"
|
android:id="@+id/account_spinner"
|
||||||
layout="@layout/action_bar_current_mailbox"
|
layout="@layout/action_bar_spinner"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
/>
|
/>
|
||||||
<include
|
<include
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2011 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="@dimen/account_spinner_width"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
style="@android:style/Widget.Holo.Spinner"
|
||||||
|
>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/spinner_line_1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dip"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textSize="16dip"
|
||||||
|
android:textColor="@color/text_primary_color"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/spinner_line_2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12dip"
|
||||||
|
android:textColor="@color/text_primary_color"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/spinner_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dip"
|
||||||
|
android:textSize="16dip"
|
||||||
|
android:textColor="@color/text_primary_color"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="none"
|
||||||
|
android:gravity="center"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
|
@ -17,6 +17,8 @@
|
||||||
<!--
|
<!--
|
||||||
Not a RelativeLayout - we want to hide @id/email_address at runtime and then @id/display_name
|
Not a RelativeLayout - we want to hide @id/email_address at runtime and then @id/display_name
|
||||||
should be center-vertical
|
should be center-vertical
|
||||||
|
|
||||||
|
Popup width is set at runtime from @dimen/account_spinner_dropdown_width
|
||||||
-->
|
-->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
@ -25,12 +27,11 @@
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
>
|
>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dip"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:maxWidth="@dimen/account_spinner_dropdown_account_name_max_width"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="center|left"
|
android:gravity="center|left"
|
||||||
>
|
>
|
||||||
|
@ -38,14 +39,12 @@
|
||||||
android:id="@+id/display_name"
|
android:id="@+id/display_name"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxWidth="@dimen/account_spinner_dropdown_account_name_max_width"
|
|
||||||
style="@style/action_bar_account_name"
|
style="@style/action_bar_account_name"
|
||||||
/>
|
/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/email_address"
|
android:id="@+id/email_address"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxWidth="@dimen/account_spinner_dropdown_account_name_max_width"
|
|
||||||
style="@style/action_bar_account_name_secondary"
|
style="@style/action_bar_account_name_secondary"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -53,7 +53,8 @@
|
||||||
<dimen name="setup_item_inset_left">0dip</dimen>
|
<dimen name="setup_item_inset_left">0dip</dimen>
|
||||||
<dimen name="setup_item_inset_right">0dip</dimen>
|
<dimen name="setup_item_inset_right">0dip</dimen>
|
||||||
|
|
||||||
<dimen name="account_spinner_dropdown_account_name_max_width">352dip</dimen>
|
<dimen name="account_spinner_width">250dip</dimen>
|
||||||
|
<dimen name="account_spinner_dropdown_width">300dip</dimen>
|
||||||
|
|
||||||
<!-- MessageListItem -->
|
<!-- MessageListItem -->
|
||||||
<dimen name="senders_font_size">14sp</dimen>
|
<dimen name="senders_font_size">14sp</dimen>
|
||||||
|
|
|
@ -1153,6 +1153,9 @@ save attachment.</string>
|
||||||
<!-- The hint used in the search box when searching a single mailbox [CHAR LIMIT=35] -->
|
<!-- The hint used in the search box when searching a single mailbox [CHAR LIMIT=35] -->
|
||||||
<string name="search_mailbox_hint">Search <xliff:g example="Inbox">%1$s</xliff:g></string>
|
<string name="search_mailbox_hint">Search <xliff:g example="Inbox">%1$s</xliff:g></string>
|
||||||
|
|
||||||
|
<!-- Title shown on the action bar on the mailbox list screen. [CHAR LIMIT=16] -->
|
||||||
|
<string name="action_bar_mailbox_list_title">Folders</string>
|
||||||
|
|
||||||
<!-- STOPSHIP Temporary UI DO NOT TRANSLATE-->
|
<!-- STOPSHIP Temporary UI DO NOT TRANSLATE-->
|
||||||
<!-- In Mailbox setings, label for email check frequency selector -->
|
<!-- In Mailbox setings, label for email check frequency selector -->
|
||||||
<string name="mailbox_options_check_frequency_label">Folder check frequency</string>
|
<string name="mailbox_options_check_frequency_label">Folder check frequency</string>
|
||||||
|
|
|
@ -71,10 +71,7 @@ public class FolderProperties {
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getCombinedMailboxName(long mailboxId) {
|
||||||
* Lookup names of localized special mailboxes
|
|
||||||
*/
|
|
||||||
private String getDisplayName(int type, long mailboxId) {
|
|
||||||
// Special combined mailboxes
|
// Special combined mailboxes
|
||||||
int resId = 0;
|
int resId = 0;
|
||||||
|
|
||||||
|
@ -91,13 +88,21 @@ public class FolderProperties {
|
||||||
if (resId != 0) {
|
if (resId != 0) {
|
||||||
return mContext.getString(resId);
|
return mContext.getString(resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type < mSpecialMailbox.length) {
|
|
||||||
return mSpecialMailbox[type];
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup names of localized special mailboxes
|
||||||
|
*/
|
||||||
|
private String getDisplayName(int type, long mailboxId) {
|
||||||
|
String name = getCombinedMailboxName(mailboxId);
|
||||||
|
|
||||||
|
if ((name == null) && (type < mSpecialMailbox.length)) {
|
||||||
|
name = mSpecialMailbox[type];
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the display name for a mailbox for UI. For normal mailboxes, it just returns
|
* Return the display name for a mailbox for UI. For normal mailboxes, it just returns
|
||||||
* {@code originalDisplayName}, but for special mailboxes (such as combined mailboxes) it
|
* {@code originalDisplayName}, but for special mailboxes (such as combined mailboxes) it
|
||||||
|
|
|
@ -24,12 +24,14 @@ import com.android.email.data.ClosingMatrixCursor;
|
||||||
import com.android.email.data.ThrottlingCursorLoader;
|
import com.android.email.data.ThrottlingCursorLoader;
|
||||||
import com.android.emailcommon.provider.Account;
|
import com.android.emailcommon.provider.Account;
|
||||||
import com.android.emailcommon.provider.EmailContent;
|
import com.android.emailcommon.provider.EmailContent;
|
||||||
|
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||||
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
|
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
|
||||||
import com.android.emailcommon.provider.Mailbox;
|
import com.android.emailcommon.provider.Mailbox;
|
||||||
import com.android.emailcommon.utility.Utility;
|
import com.android.emailcommon.utility.Utility;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Loader;
|
import android.content.Loader;
|
||||||
|
@ -50,10 +52,16 @@ import android.widget.TextView;
|
||||||
public class AccountSelectorAdapter extends CursorAdapter {
|
public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
/** meta data column for an message count (unread or total, depending on row) */
|
/** meta data column for an message count (unread or total, depending on row) */
|
||||||
private static final String MESSAGE_COUNT = "unreadCount";
|
private static final String MESSAGE_COUNT = "unreadCount";
|
||||||
|
|
||||||
/** meta data column for the row type; used for display purposes */
|
/** meta data column for the row type; used for display purposes */
|
||||||
private static final String ROW_TYPE = "rowType";
|
private static final String ROW_TYPE = "rowType";
|
||||||
|
|
||||||
/** meta data position of the currently selected account in the drop-down list */
|
/** meta data position of the currently selected account in the drop-down list */
|
||||||
private static final String ACCOUNT_POSITION = "accountPosition";
|
private static final String ACCOUNT_POSITION = "accountPosition";
|
||||||
|
|
||||||
|
/** "account id" virtual column name for the matrix cursor */
|
||||||
|
private static final String ACCOUNT_ID = "accountId";
|
||||||
|
|
||||||
private static final int ROW_TYPE_HEADER = AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
|
private static final int ROW_TYPE_HEADER = AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static final int ROW_TYPE_MAILBOX = 0;
|
private static final int ROW_TYPE_MAILBOX = 0;
|
||||||
|
@ -77,6 +85,7 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
Account.EMAIL_ADDRESS,
|
Account.EMAIL_ADDRESS,
|
||||||
MESSAGE_COUNT,
|
MESSAGE_COUNT,
|
||||||
ACCOUNT_POSITION,
|
ACCOUNT_POSITION,
|
||||||
|
ACCOUNT_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Sort order. Show the default account first. */
|
/** Sort order. Show the default account first. */
|
||||||
|
@ -92,8 +101,8 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
* @param context a context
|
* @param context a context
|
||||||
* @param accountId the ID of the currently viewed account
|
* @param accountId the ID of the currently viewed account
|
||||||
*/
|
*/
|
||||||
public static Loader<Cursor> createLoader(Context context, long accountId) {
|
public static Loader<Cursor> createLoader(Context context, long accountId, long mailboxId) {
|
||||||
return new AccountsLoader(context, accountId, UiUtilities.useTwoPane(context));
|
return new AccountsLoader(context, accountId, mailboxId, UiUtilities.useTwoPane(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountSelectorAdapter(Context context) {
|
public AccountSelectorAdapter(Context context) {
|
||||||
|
@ -103,22 +112,8 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the action bar needs the view of the text in the bar itself. The default
|
* {@inheritDoc}
|
||||||
* is to show just the display name of the cursor at the given position.
|
*
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
if (!isAccountItem(position)) {
|
|
||||||
// asked to show a recent mailbox; instead, show the account associated w/ the mailbox
|
|
||||||
int newPosition = getAccountPosition(position);
|
|
||||||
if (newPosition != UNKNOWN_POSITION) {
|
|
||||||
position = newPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.getView(position, convertView, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The account selector view can contain one of four types of row data:
|
* The account selector view can contain one of four types of row data:
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>headers</li>
|
* <li>headers</li>
|
||||||
|
@ -132,26 +127,27 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
* mailboxes display an unread count; whereas "show all folders" does not. To determine
|
* mailboxes display an unread count; whereas "show all folders" does not. To determine
|
||||||
* if a particular row is "show all folders" verify that a) it's not an account row and
|
* if a particular row is "show all folders" verify that a) it's not an account row and
|
||||||
* b) it's ID is {@link Mailbox#NO_MAILBOX}.
|
* b) it's ID is {@link Mailbox#NO_MAILBOX}.
|
||||||
|
*
|
||||||
|
* TODO Use recycled views. ({@link #getViewTypeCount} and {@link #getItemViewType})
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public View getDropDownView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
Cursor c = getCursor();
|
Cursor c = getCursor();
|
||||||
c.moveToPosition(position);
|
c.moveToPosition(position);
|
||||||
|
|
||||||
View view;
|
View view;
|
||||||
if (c.getInt(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_HEADER) {
|
if (c.getInt(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_HEADER) {
|
||||||
view = mInflater.inflate(R.layout.account_selector_dropdown_header, parent, false);
|
view = mInflater.inflate(R.layout.action_bar_spinner_dropdown_header, parent, false);
|
||||||
final TextView displayNameView = (TextView) view.findViewById(R.id.display_name);
|
final TextView displayNameView = (TextView) view.findViewById(R.id.display_name);
|
||||||
final String displayName = getDisplayName(c);
|
final String displayName = getDisplayName(c);
|
||||||
displayNameView.setText(displayName);
|
displayNameView.setText(displayName);
|
||||||
} else {
|
} else {
|
||||||
view = mInflater.inflate(R.layout.account_selector_dropdown, parent, false);
|
view = mInflater.inflate(R.layout.action_bar_spinner_dropdown, parent, false);
|
||||||
final TextView displayNameView = (TextView) view.findViewById(R.id.display_name);
|
final TextView displayNameView = (TextView) view.findViewById(R.id.display_name);
|
||||||
final TextView emailAddressView = (TextView) view.findViewById(R.id.email_address);
|
final TextView emailAddressView = (TextView) view.findViewById(R.id.email_address);
|
||||||
final TextView unreadCountView = (TextView) view.findViewById(R.id.unread_count);
|
final TextView unreadCountView = (TextView) view.findViewById(R.id.unread_count);
|
||||||
|
|
||||||
final String displayName = getDisplayName(position);
|
final String displayName = getDisplayName(c);
|
||||||
final String emailAddress = getAccountEmailAddress(position);
|
final String emailAddress = getAccountEmailAddress(c);
|
||||||
|
|
||||||
displayNameView.setText(displayName);
|
displayNameView.setText(displayName);
|
||||||
|
|
||||||
|
@ -163,12 +159,12 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
emailAddressView.setText(emailAddress);
|
emailAddressView.setText(emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAccount = isAccountItem(position);
|
boolean isAccount = isAccountItem(c);
|
||||||
long id = getId(c);
|
long id = getId(c);
|
||||||
if (isAccount || id != Mailbox.NO_MAILBOX) {
|
if (isAccount || id != Mailbox.NO_MAILBOX) {
|
||||||
unreadCountView.setVisibility(View.VISIBLE);
|
unreadCountView.setVisibility(View.VISIBLE);
|
||||||
unreadCountView.setText(UiUtilities.getMessageCountForUi(mContext,
|
unreadCountView.setText(UiUtilities.getMessageCountForUi(mContext,
|
||||||
getAccountUnreadCount(position), true));
|
getAccountUnreadCount(c), true));
|
||||||
} else {
|
} else {
|
||||||
unreadCountView.setVisibility(View.INVISIBLE);
|
unreadCountView.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -177,14 +173,13 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindView(View view, Context context, Cursor cursor) {
|
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||||
TextView textView = (TextView) view.findViewById(R.id.display_name);
|
return null; // we don't reuse views. This method never gets called.
|
||||||
textView.setText(getDisplayName(cursor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
public void bindView(View view, Context context, Cursor cursor) {
|
||||||
return mInflater.inflate(R.layout.account_selector, parent, false);
|
// we don't reuse views. This method never gets called.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -209,6 +204,10 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
public boolean isAccountItem(int position) {
|
public boolean isAccountItem(int position) {
|
||||||
Cursor c = getCursor();
|
Cursor c = getCursor();
|
||||||
c.moveToPosition(position);
|
c.moveToPosition(position);
|
||||||
|
return isAccountItem(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccountItem(Cursor c) {
|
||||||
return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_ACCOUNT);
|
return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_ACCOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,24 +217,8 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_MAILBOX);
|
return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_MAILBOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDisplayName(int position) {
|
private int getAccountUnreadCount(Cursor c) {
|
||||||
final Cursor c = getCursor();
|
return getMessageCount(c);
|
||||||
return c.moveToPosition(position) ? getDisplayName(c) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getAccountEmailAddress(int position) {
|
|
||||||
final Cursor c = getCursor();
|
|
||||||
return c.moveToPosition(position) ? getAccountEmailAddress(c) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getAccountUnreadCount(int position) {
|
|
||||||
final Cursor c = getCursor();
|
|
||||||
return c.moveToPosition(position) ? getMessageCount(c) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getAccountPosition(int position) {
|
|
||||||
final Cursor c = getCursor();
|
|
||||||
return c.moveToPosition(position) ? getAccountPosition(c) : UNKNOWN_POSITION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,6 +228,24 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
return c.getLong(c.getColumnIndex(EmailContent.RECORD_ID));
|
return c.getLong(c.getColumnIndex(EmailContent.RECORD_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ID of the account / mailbox for a row
|
||||||
|
*/
|
||||||
|
public long getId(int position) {
|
||||||
|
final Cursor c = getCursor();
|
||||||
|
return c.moveToPosition(position) ? getId(c) : Account.NO_ACCOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ID of the account for a row
|
||||||
|
*/
|
||||||
|
public long getAccountId(int position) {
|
||||||
|
final Cursor c = getCursor();
|
||||||
|
return c.moveToPosition(position)
|
||||||
|
? c.getLong(c.getColumnIndex(ACCOUNT_ID))
|
||||||
|
: Account.NO_ACCOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the account name extracted from the given cursor. */
|
/** Returns the account name extracted from the given cursor. */
|
||||||
static String getDisplayName(Cursor cursor) {
|
static String getDisplayName(Cursor cursor) {
|
||||||
return cursor.getString(cursor.getColumnIndex(Account.DISPLAY_NAME));
|
return cursor.getString(cursor.getColumnIndex(Account.DISPLAY_NAME));
|
||||||
|
@ -263,9 +264,13 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
return cursor.getInt(cursor.getColumnIndex(MESSAGE_COUNT));
|
return cursor.getInt(cursor.getColumnIndex(MESSAGE_COUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the account position extracted from the given cursor. */
|
private static String sCombinedViewDisplayName;
|
||||||
private static int getAccountPosition(Cursor cursor) {
|
private static String getCombinedViewDisplayName(Context c) {
|
||||||
return cursor.getInt(cursor.getColumnIndex(ACCOUNT_POSITION));
|
if (sCombinedViewDisplayName == null) {
|
||||||
|
sCombinedViewDisplayName = c.getResources().getString(
|
||||||
|
R.string.mailbox_list_account_selector_combined_view);
|
||||||
|
}
|
||||||
|
return sCombinedViewDisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,16 +283,18 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
static class AccountsLoader extends ThrottlingCursorLoader {
|
static class AccountsLoader extends ThrottlingCursorLoader {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final long mAccountId;
|
private final long mAccountId;
|
||||||
|
private final long mMailboxId;
|
||||||
private final boolean mUseTwoPane; // Injectable for test
|
private final boolean mUseTwoPane; // Injectable for test
|
||||||
private final FolderProperties mFolderProperties;
|
private final FolderProperties mFolderProperties;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
AccountsLoader(Context context, long accountId, boolean useTwoPane) {
|
AccountsLoader(Context context, long accountId, long mailboxId, boolean useTwoPane) {
|
||||||
// Super class loads a regular account cursor, but we replace it in loadInBackground().
|
// Super class loads a regular account cursor, but we replace it in loadInBackground().
|
||||||
super(context, Account.CONTENT_URI, ACCOUNT_PROJECTION, null, null,
|
super(context, Account.CONTENT_URI, ACCOUNT_PROJECTION, null, null,
|
||||||
ORDER_BY);
|
ORDER_BY);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAccountId = accountId;
|
mAccountId = accountId;
|
||||||
|
mMailboxId = mailboxId;
|
||||||
mFolderProperties = FolderProperties.getInstance(mContext);
|
mFolderProperties = FolderProperties.getInstance(mContext);
|
||||||
mUseTwoPane = useTwoPane;
|
mUseTwoPane = useTwoPane;
|
||||||
}
|
}
|
||||||
|
@ -300,17 +307,19 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
= new CursorWithExtras(ADAPTER_PROJECTION, accountsCursor);
|
= new CursorWithExtras(ADAPTER_PROJECTION, accountsCursor);
|
||||||
final int accountPosition = addAccountsToCursor(resultCursor, accountsCursor);
|
final int accountPosition = addAccountsToCursor(resultCursor, accountsCursor);
|
||||||
addRecentsToCursor(resultCursor, accountPosition);
|
addRecentsToCursor(resultCursor, accountPosition);
|
||||||
return Utility.CloseTraceCursorWrapper.get(resultCursor);
|
|
||||||
|
resultCursor.setAccountMailboxInfo(getContext(), mAccountId, mMailboxId);
|
||||||
|
return resultCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the account list [with extra meta data] to the given matrix cursor */
|
/** Adds the account list [with extra meta data] to the given matrix cursor */
|
||||||
private int addAccountsToCursor(CursorWithExtras matrixCursor, Cursor accountCursor) {
|
private int addAccountsToCursor(CursorWithExtras matrixCursor, Cursor accountCursor) {
|
||||||
int accountPosition = UNKNOWN_POSITION;
|
int accountPosition = UNKNOWN_POSITION;
|
||||||
accountCursor.moveToPosition(-1);
|
accountCursor.moveToPosition(-1);
|
||||||
|
|
||||||
// Add a header for the accounts
|
// Add a header for the accounts
|
||||||
String header =
|
addHeaderRow(matrixCursor, mContext.getString(
|
||||||
mContext.getString(R.string.mailbox_list_account_selector_account_header);
|
R.string.mailbox_list_account_selector_account_header));
|
||||||
addRow(matrixCursor, ROW_TYPE_HEADER, 0L, header, null, 0, UNKNOWN_POSITION);
|
|
||||||
|
|
||||||
matrixCursor.mAccountCount = accountCursor.getCount();
|
matrixCursor.mAccountCount = accountCursor.getCount();
|
||||||
int totalUnread = 0;
|
int totalUnread = 0;
|
||||||
|
@ -323,7 +332,7 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
final String name = getDisplayName(accountCursor);
|
final String name = getDisplayName(accountCursor);
|
||||||
final String emailAddress = getAccountEmailAddress(accountCursor);
|
final String emailAddress = getAccountEmailAddress(accountCursor);
|
||||||
addRow(matrixCursor, ROW_TYPE_ACCOUNT, accountId, name, emailAddress, unread,
|
addRow(matrixCursor, ROW_TYPE_ACCOUNT, accountId, name, emailAddress, unread,
|
||||||
UNKNOWN_POSITION);
|
UNKNOWN_POSITION, accountId);
|
||||||
totalUnread += unread;
|
totalUnread += unread;
|
||||||
if (accountId == mAccountId) {
|
if (accountId == mAccountId) {
|
||||||
accountPosition = currentPosition;
|
accountPosition = currentPosition;
|
||||||
|
@ -333,12 +342,12 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
// Add "combined view" if more than one account exists
|
// Add "combined view" if more than one account exists
|
||||||
final int countAccounts = accountCursor.getCount();
|
final int countAccounts = accountCursor.getCount();
|
||||||
if (countAccounts > 1) {
|
if (countAccounts > 1) {
|
||||||
final String name = mContext.getResources().getString(
|
|
||||||
R.string.mailbox_list_account_selector_combined_view);
|
|
||||||
final String accountCount = mContext.getResources().getQuantityString(
|
final String accountCount = mContext.getResources().getQuantityString(
|
||||||
R.plurals.number_of_accounts, countAccounts, countAccounts);
|
R.plurals.number_of_accounts, countAccounts, countAccounts);
|
||||||
addRow(matrixCursor, ROW_TYPE_ACCOUNT, Account.ACCOUNT_ID_COMBINED_VIEW,
|
addRow(matrixCursor, ROW_TYPE_ACCOUNT, Account.ACCOUNT_ID_COMBINED_VIEW,
|
||||||
name, accountCount, totalUnread, UNKNOWN_POSITION);
|
getCombinedViewDisplayName(mContext),
|
||||||
|
accountCount, totalUnread, UNKNOWN_POSITION,
|
||||||
|
Account.ACCOUNT_ID_COMBINED_VIEW);
|
||||||
|
|
||||||
// Increment the account count for the combined account.
|
// Increment the account count for the combined account.
|
||||||
matrixCursor.mAccountCount++;
|
matrixCursor.mAccountCount++;
|
||||||
|
@ -373,9 +382,8 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
|
|
||||||
if (!mUseTwoPane) {
|
if (!mUseTwoPane) {
|
||||||
// "Recent mailboxes" header
|
// "Recent mailboxes" header
|
||||||
String mailboxHeader = mContext.getString(
|
addHeaderRow(matrixCursor, mContext.getString(
|
||||||
R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress);
|
R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress));
|
||||||
addRow(matrixCursor, ROW_TYPE_HEADER, 0L, mailboxHeader, null, 0, UNKNOWN_POSITION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recentCount > 0) {
|
if (recentCount > 0) {
|
||||||
|
@ -389,7 +397,7 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
String name = mContext.getString(
|
String name = mContext.getString(
|
||||||
R.string.mailbox_list_account_selector_show_all_folders);
|
R.string.mailbox_list_account_selector_show_all_folders);
|
||||||
addRow(matrixCursor, ROW_TYPE_MAILBOX, Mailbox.NO_MAILBOX, name, null, 0,
|
addRow(matrixCursor, ROW_TYPE_MAILBOX, Mailbox.NO_MAILBOX, name, null, 0,
|
||||||
accountPosition);
|
accountPosition, mAccountId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,33 +416,114 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
}
|
}
|
||||||
addRow(matrixCursor, ROW_TYPE_MAILBOX, mailboxId,
|
addRow(matrixCursor, ROW_TYPE_MAILBOX, mailboxId,
|
||||||
mFolderProperties.getDisplayName(c), null,
|
mFolderProperties.getDisplayName(c), null,
|
||||||
mFolderProperties.getMessageCount(c), accountPosition);
|
mFolderProperties.getMessageCount(c), accountPosition, mAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeaderRow(MatrixCursor cursor, String name) {
|
||||||
|
addRow(cursor, ROW_TYPE_HEADER, 0L, name, null, 0, UNKNOWN_POSITION,
|
||||||
|
Account.NO_ACCOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a row to the given cursor */
|
/** Adds a row to the given cursor */
|
||||||
private void addRow(MatrixCursor cursor, int rowType, long id, String name,
|
private void addRow(MatrixCursor cursor, int rowType, long id, String name,
|
||||||
String emailAddress, int messageCount, int listPosition) {
|
String emailAddress, int messageCount, int listPosition, long accountId) {
|
||||||
cursor.newRow()
|
cursor.newRow()
|
||||||
.add(rowType)
|
.add(rowType)
|
||||||
.add(id)
|
.add(id)
|
||||||
.add(name)
|
.add(name)
|
||||||
.add(emailAddress)
|
.add(emailAddress)
|
||||||
.add(messageCount)
|
.add(messageCount)
|
||||||
.add(listPosition);
|
.add(listPosition)
|
||||||
|
.add(accountId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cursor with some extra meta data. */
|
/** Cursor with some extra meta data. */
|
||||||
static class CursorWithExtras extends ClosingMatrixCursor {
|
static class CursorWithExtras extends ClosingMatrixCursor {
|
||||||
|
|
||||||
/** Number of account elements, including the combined account row. */
|
/** Number of account elements, including the combined account row. */
|
||||||
private int mAccountCount;
|
private int mAccountCount;
|
||||||
/** Number of recent mailbox elements */
|
/** Number of recent mailbox elements */
|
||||||
private int mRecentCount;
|
private int mRecentCount;
|
||||||
|
|
||||||
|
private boolean mAccountExists;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account ID that's loaded.
|
||||||
|
*/
|
||||||
|
private long mAccountId;
|
||||||
|
private String mAccountDisplayName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mailbox ID that's loaded.
|
||||||
|
*/
|
||||||
|
private long mMailboxId;
|
||||||
|
private String mMailboxDisplayName;
|
||||||
|
private int mMailboxMessageCount;
|
||||||
|
|
||||||
private CursorWithExtras(String[] columnNames, Cursor innerCursor) {
|
private CursorWithExtras(String[] columnNames, Cursor innerCursor) {
|
||||||
super(columnNames, innerCursor);
|
super(columnNames, innerCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String[] ACCOUNT_INFO_PROJECTION = new String[] {
|
||||||
|
AccountColumns.DISPLAY_NAME,
|
||||||
|
};
|
||||||
|
private static final String[] MAILBOX_INFO_PROJECTION = new String[] {
|
||||||
|
MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE,
|
||||||
|
MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current account/mailbox info.
|
||||||
|
*/
|
||||||
|
private void setAccountMailboxInfo(Context context, long accountId, long mailboxId) {
|
||||||
|
mAccountId = accountId;
|
||||||
|
mMailboxId = mailboxId;
|
||||||
|
|
||||||
|
// Get account info
|
||||||
|
if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||||
|
// We need to treat ACCOUNT_ID_COMBINED_VIEW specially...
|
||||||
|
mAccountExists = true;
|
||||||
|
mAccountDisplayName = getCombinedViewDisplayName(context);
|
||||||
|
mMailboxDisplayName = FolderProperties.getInstance(context)
|
||||||
|
.getCombinedMailboxName(mMailboxId);
|
||||||
|
|
||||||
|
// TODO Would be nicer to show message count for combined mailboxes too..
|
||||||
|
mMailboxMessageCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAccountDisplayName = Utility.getFirstRowString(context,
|
||||||
|
ContentUris.withAppendedId(Account.CONTENT_URI, accountId),
|
||||||
|
ACCOUNT_INFO_PROJECTION, null, null, null, 0, null);
|
||||||
|
if (mAccountDisplayName == null) {
|
||||||
|
// Account gone!
|
||||||
|
mAccountExists = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAccountExists = true;
|
||||||
|
|
||||||
|
// If mailbox not specified, done.
|
||||||
|
if (mMailboxId == Mailbox.NO_MAILBOX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get mailbox info
|
||||||
|
final ContentResolver r = context.getContentResolver();
|
||||||
|
final Cursor mailboxCursor = r.query(
|
||||||
|
ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
|
||||||
|
MAILBOX_INFO_PROJECTION, null, null, null);
|
||||||
|
try {
|
||||||
|
if (mailboxCursor.moveToFirst()) {
|
||||||
|
final FolderProperties fp = FolderProperties.getInstance(context);
|
||||||
|
mMailboxDisplayName = fp.getDisplayName(mailboxCursor);
|
||||||
|
mMailboxMessageCount = fp.getMessageCount(mailboxCursor);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
mailboxCursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cursor position of the item with the given ID. Or {@link #UNKNOWN_POSITION}
|
* Returns the cursor position of the item with the given ID. Or {@link #UNKNOWN_POSITION}
|
||||||
* if the given ID does not exist.
|
* if the given ID does not exist.
|
||||||
|
@ -456,5 +545,32 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
public int getRecentMailboxCount() {
|
public int getRecentMailboxCount() {
|
||||||
return mRecentCount;
|
return mRecentCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getAccountId() {
|
||||||
|
return mAccountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountDisplayName() {
|
||||||
|
return mAccountDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMailboxId() {
|
||||||
|
return mMailboxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMailboxDisplayName() {
|
||||||
|
return mMailboxDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMailboxMessageCount() {
|
||||||
|
return mMailboxMessageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the specified accuont exists.
|
||||||
|
*/
|
||||||
|
public boolean accountExists() {
|
||||||
|
return mAccountExists;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,30 +16,29 @@
|
||||||
|
|
||||||
package com.android.email.activity;
|
package com.android.email.activity;
|
||||||
|
|
||||||
|
import com.android.email.R;
|
||||||
|
import com.android.emailcommon.provider.Account;
|
||||||
|
import com.android.emailcommon.provider.Mailbox;
|
||||||
|
import com.android.emailcommon.utility.Utility;
|
||||||
|
|
||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
import android.app.LoaderManager;
|
import android.app.LoaderManager;
|
||||||
import android.app.LoaderManager.LoaderCallbacks;
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Loader;
|
import android.content.Loader;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
|
import android.widget.ListPopupWindow;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.SearchView;
|
import android.widget.SearchView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.email.FolderProperties;
|
|
||||||
import com.android.email.R;
|
|
||||||
import com.android.email.data.ThrottlingCursorLoader;
|
|
||||||
import com.android.emailcommon.Logging;
|
|
||||||
import com.android.emailcommon.provider.Account;
|
|
||||||
import com.android.emailcommon.provider.EmailContent;
|
|
||||||
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
|
|
||||||
import com.android.emailcommon.provider.Mailbox;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the account name and the custom view part on the action bar.
|
* Manages the account name and the custom view part on the action bar.
|
||||||
*
|
*
|
||||||
|
@ -68,25 +67,29 @@ public class ActionBarController {
|
||||||
|
|
||||||
private static final int LOADER_ID_ACCOUNT_LIST
|
private static final int LOADER_ID_ACCOUNT_LIST
|
||||||
= EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 0;
|
= EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 0;
|
||||||
private static final int LOADER_ID_MAILBOX
|
|
||||||
= EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 1;
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final LoaderManager mLoaderManager;
|
private final LoaderManager mLoaderManager;
|
||||||
private final ActionBar mActionBar;
|
private final ActionBar mActionBar;
|
||||||
|
|
||||||
|
/** "Folders" label shown with account name on 1-pane mailbox list */
|
||||||
|
private final String mAllFoldersLabel;
|
||||||
|
|
||||||
private final View mActionBarCustomView;
|
private final View mActionBarCustomView;
|
||||||
private final View mMailboxNameContainer;
|
private final View mAccountSpinner;
|
||||||
private final TextView mMailboxNameView;
|
private final TextView mAccountSpinnerLine1View;
|
||||||
private final TextView mUnreadCountView;
|
private final TextView mAccountSpinnerLine2View;
|
||||||
|
private final TextView mAccountSpinnerCountView;
|
||||||
|
|
||||||
private final View mSearchContainer;
|
private final View mSearchContainer;
|
||||||
private final SearchView mSearchView;
|
private final SearchView mSearchView;
|
||||||
|
|
||||||
private final ActionBarNavigationCallback mActionBarNavigationCallback =
|
private final AccountDropdownPopup mAccountDropdown;
|
||||||
new ActionBarNavigationCallback();
|
|
||||||
|
|
||||||
private final AccountSelectorAdapter mAccountsSelectorAdapter;
|
private final AccountSelectorAdapter mAccountsSelectorAdapter;
|
||||||
private AccountSelectorAdapter.CursorWithExtras mAccountCursor;
|
|
||||||
|
private AccountSelectorAdapter.CursorWithExtras mCursor;
|
||||||
|
|
||||||
/** The current account ID; used to determine if the account has changed. */
|
/** The current account ID; used to determine if the account has changed. */
|
||||||
private long mLastAccountIdForDirtyCheck = Account.NO_ACCOUNT;
|
private long mLastAccountIdForDirtyCheck = Account.NO_ACCOUNT;
|
||||||
|
|
||||||
|
@ -103,6 +106,20 @@ public class ActionBarController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
|
/** Values for {@link #getTitleMode}. Show only account name */
|
||||||
|
public static final int TITLE_MODE_ACCOUNT_NAME_ONLY = 0;
|
||||||
|
/** Show the current account name with "Folders" */
|
||||||
|
public static final int TITLE_MODE_ACCOUNT_WITH_ALL_FOLDERS_LABEL = 1;
|
||||||
|
/** Show the current account name and the current mailbox name */
|
||||||
|
public static final int TITLE_MODE_ACCOUNT_WITH_MAILBOX = 2;
|
||||||
|
/**
|
||||||
|
* Show the current message subject. Actual subject is obtained via
|
||||||
|
* {@link #getMessageSubject()}.
|
||||||
|
*
|
||||||
|
* NOT IMPLEMENTED YET
|
||||||
|
*/
|
||||||
|
public static final int TITLE_MODE_MESSAGE_SUBJECT = 3;
|
||||||
|
|
||||||
/** @return true if an account is selected. */
|
/** @return true if an account is selected. */
|
||||||
public boolean isAccountSelected();
|
public boolean isAccountSelected();
|
||||||
|
|
||||||
|
@ -118,8 +135,13 @@ public class ActionBarController {
|
||||||
*/
|
*/
|
||||||
public long getMailboxId();
|
public long getMailboxId();
|
||||||
|
|
||||||
/** @return true if the current mailbox name should be shown. */
|
/**
|
||||||
public boolean shouldShowMailboxName();
|
* @return constants such as {@link #TITLE_MODE_ACCOUNT_NAME_ONLY}.
|
||||||
|
*/
|
||||||
|
public int getTitleMode();
|
||||||
|
|
||||||
|
/** @see #TITLE_MODE_MESSAGE_SUBJECT */
|
||||||
|
public String getMessageSubject();
|
||||||
|
|
||||||
/** @return the "UP" arrow should be shown. */
|
/** @return the "UP" arrow should be shown. */
|
||||||
public boolean shouldShowUp();
|
public boolean shouldShowUp();
|
||||||
|
@ -132,10 +154,12 @@ public class ActionBarController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when a recent mailbox is selected on the account spinner.
|
* Invoked when a recent mailbox is selected on the account spinner.
|
||||||
|
*
|
||||||
|
* @param accountId ID of the selected account, or {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
||||||
* @param mailboxId The ID of the selected mailbox, or {@link Mailbox#NO_MAILBOX} if the
|
* @param mailboxId The ID of the selected mailbox, or {@link Mailbox#NO_MAILBOX} if the
|
||||||
* special option "show all mailboxes" was selected.
|
* special option "show all mailboxes" was selected.
|
||||||
*/
|
*/
|
||||||
public void onMailboxSelected(long mailboxId);
|
public void onMailboxSelected(long accountId, long mailboxId);
|
||||||
|
|
||||||
/** Called when no accounts are found in the database. */
|
/** Called when no accounts are found in the database. */
|
||||||
public void onNoAccountsFound();
|
public void onNoAccountsFound();
|
||||||
|
@ -159,42 +183,58 @@ public class ActionBarController {
|
||||||
mLoaderManager = loaderManager;
|
mLoaderManager = loaderManager;
|
||||||
mActionBar = actionBar;
|
mActionBar = actionBar;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
|
mAllFoldersLabel = mContext.getResources().getString(
|
||||||
|
R.string.action_bar_mailbox_list_title);
|
||||||
mAccountsSelectorAdapter = new AccountSelectorAdapter(mContext);
|
mAccountsSelectorAdapter = new AccountSelectorAdapter(mContext);
|
||||||
|
|
||||||
mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE
|
// Configure action bar.
|
||||||
| ActionBar.DISPLAY_SHOW_HOME
|
mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM);
|
||||||
| ActionBar.DISPLAY_SHOW_CUSTOM);
|
|
||||||
|
|
||||||
// Prepare the custom view
|
// Prepare the custom view
|
||||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
mActionBarCustomView = inflater.inflate(R.layout.action_bar_custom_view, null);
|
mActionBarCustomView = inflater.inflate(R.layout.action_bar_custom_view, null);
|
||||||
final ActionBar.LayoutParams customViewLayout = new ActionBar.LayoutParams(
|
final ActionBar.LayoutParams customViewLayout = new ActionBar.LayoutParams(
|
||||||
ActionBar.LayoutParams.MATCH_PARENT,
|
ActionBar.LayoutParams.WRAP_CONTENT,
|
||||||
ActionBar.LayoutParams.MATCH_PARENT);
|
ActionBar.LayoutParams.MATCH_PARENT);
|
||||||
customViewLayout.setMargins(0 , 0, 0, 0);
|
customViewLayout.setMargins(0, 0, 0, 0);
|
||||||
mActionBar.setCustomView(mActionBarCustomView, customViewLayout);
|
mActionBar.setCustomView(mActionBarCustomView, customViewLayout);
|
||||||
|
|
||||||
// Mailbox name / unread count
|
// Account spinner
|
||||||
mMailboxNameContainer = UiUtilities.getView(mActionBarCustomView,
|
mAccountSpinner = UiUtilities.getView(mActionBarCustomView, R.id.account_spinner);
|
||||||
R.id.current_mailbox_container);
|
|
||||||
mMailboxNameView = UiUtilities.getView(mMailboxNameContainer, R.id.mailbox_name);
|
mAccountSpinnerLine1View = UiUtilities.getView(mActionBarCustomView, R.id.spinner_line_1);
|
||||||
mUnreadCountView = UiUtilities.getView(mMailboxNameContainer, R.id.unread_count);
|
mAccountSpinnerLine2View = UiUtilities.getView(mActionBarCustomView, R.id.spinner_line_2);
|
||||||
|
mAccountSpinnerCountView = UiUtilities.getView(mActionBarCustomView, R.id.spinner_count);
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
mSearchContainer = UiUtilities.getView(mActionBarCustomView, R.id.search_container);
|
mSearchContainer = UiUtilities.getView(mActionBarCustomView, R.id.search_container);
|
||||||
mSearchView = UiUtilities.getView(mSearchContainer, R.id.search_view);
|
mSearchView = UiUtilities.getView(mSearchContainer, R.id.search_view);
|
||||||
mSearchView.setSubmitButtonEnabled(true);
|
mSearchView.setSubmitButtonEnabled(true);
|
||||||
mSearchView.setOnQueryTextListener(mOnQueryText);
|
mSearchView.setOnQueryTextListener(mOnQueryText);
|
||||||
|
|
||||||
|
// Account dropdown
|
||||||
|
mAccountDropdown = new AccountDropdownPopup(mContext);
|
||||||
|
mAccountDropdown.setAdapter(mAccountsSelectorAdapter);
|
||||||
|
|
||||||
|
mAccountSpinner.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override public void onClick(View v) {
|
||||||
|
if (mAccountsSelectorAdapter.getCount() > 0) {
|
||||||
|
mAccountDropdown.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Must be called from {@link UIControllerBase#onActivityCreated()} */
|
/** Must be called from {@link UIControllerBase#onActivityCreated()} */
|
||||||
public void onActivityCreated() {
|
public void onActivityCreated() {
|
||||||
loadAccounts();
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Must be called from {@link UIControllerBase#onActivityDestroy()} */
|
/** Must be called from {@link UIControllerBase#onActivityDestroy()} */
|
||||||
public void onActivityDestroy() {
|
public void onActivityDestroy() {
|
||||||
|
if (mAccountDropdown.isShowing()) {
|
||||||
|
mAccountDropdown.dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Must be called from {@link UIControllerBase#onSaveInstanceState} */
|
/** Must be called from {@link UIControllerBase#onSaveInstanceState} */
|
||||||
|
@ -234,11 +274,6 @@ public class ActionBarController {
|
||||||
}
|
}
|
||||||
mSearchMode = MODE_SEARCH;
|
mSearchMode = MODE_SEARCH;
|
||||||
|
|
||||||
// Need to force it to mode "standard" to hide it.
|
|
||||||
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
|
||||||
mActionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
|
|
||||||
mSearchContainer.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
// Focus on the search input box and throw up the IME if specified.
|
// Focus on the search input box and throw up the IME if specified.
|
||||||
// TODO: HACK. this is a workaround IME not popping up.
|
// TODO: HACK. this is a workaround IME not popping up.
|
||||||
mSearchView.setIconified(false);
|
mSearchView.setIconified(false);
|
||||||
|
@ -251,11 +286,6 @@ public class ActionBarController {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mSearchMode = MODE_NORMAL;
|
mSearchMode = MODE_NORMAL;
|
||||||
mSearchContainer.setVisibility(View.GONE);
|
|
||||||
mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
|
|
||||||
|
|
||||||
// Force update of account list when we exit search.
|
|
||||||
updateAccountList();
|
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
mCallback.onSearchExit();
|
mCallback.onSearchExit();
|
||||||
|
@ -277,187 +307,141 @@ public class ActionBarController {
|
||||||
|
|
||||||
/** Refreshes the action bar display. */
|
/** Refreshes the action bar display. */
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
|
// The actual work is in refreshInernal(), but we don't call it directly here, because:
|
||||||
|
// 1. refresh() is called very often.
|
||||||
|
// 2. to avoid nested fragment transaction.
|
||||||
|
// refresh is often called during a fragment transaction, but updateTitle() may call
|
||||||
|
// a callback which would initiate another fragment transaction.
|
||||||
|
final Handler h = Utility.getMainThreadHandler();
|
||||||
|
h.removeCallbacks(mRefreshRunnable);
|
||||||
|
h.post(mRefreshRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Runnable mRefreshRunnable = new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
refreshInernal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private void refreshInernal() {
|
||||||
final boolean showUp = isInSearchMode() || mCallback.shouldShowUp();
|
final boolean showUp = isInSearchMode() || mCallback.shouldShowUp();
|
||||||
mActionBar.setDisplayOptions(showUp
|
mActionBar.setDisplayOptions(showUp
|
||||||
? ActionBar.DISPLAY_HOME_AS_UP : 0, ActionBar.DISPLAY_HOME_AS_UP);
|
? ActionBar.DISPLAY_HOME_AS_UP : 0, ActionBar.DISPLAY_HOME_AS_UP);
|
||||||
|
|
||||||
if (isInSearchMode()) {
|
final long accountId = mCallback.getUIAccountId();
|
||||||
mMailboxNameContainer.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
mMailboxNameContainer.setVisibility(mCallback.shouldShowMailboxName()
|
|
||||||
? View.VISIBLE : View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the account list only when the account has changed.
|
|
||||||
if (mLastAccountIdForDirtyCheck != mCallback.getUIAccountId()) {
|
|
||||||
mLastAccountIdForDirtyCheck = mCallback.getUIAccountId();
|
|
||||||
// If the selected account changes, reload the cursor to update the recent mailboxes
|
|
||||||
if (mLastAccountIdForDirtyCheck != Account.NO_ACCOUNT) {
|
|
||||||
mLoaderManager.destroyLoader(LOADER_ID_ACCOUNT_LIST);
|
|
||||||
loadAccounts();
|
|
||||||
} else {
|
|
||||||
updateAccountList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update current mailbox info
|
|
||||||
final long mailboxId = mCallback.getMailboxId();
|
final long mailboxId = mCallback.getMailboxId();
|
||||||
if (mailboxId == Mailbox.NO_MAILBOX) {
|
if ((mLastAccountIdForDirtyCheck != accountId)
|
||||||
clearMailboxInfo();
|
|| (mLastMailboxIdForDirtyCheck != mailboxId)) {
|
||||||
} else {
|
mLastAccountIdForDirtyCheck = accountId;
|
||||||
if (mLastMailboxIdForDirtyCheck != mailboxId) {
|
mLastMailboxIdForDirtyCheck = mailboxId;
|
||||||
mLastMailboxIdForDirtyCheck = mailboxId;
|
|
||||||
loadMailboxInfo(mailboxId);
|
if (accountId != Account.NO_ACCOUNT) {
|
||||||
|
loadAccountMailboxInfo(accountId, mailboxId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load account cursor, and update the action bar.
|
* Load account/mailbox info, and account/recent mailbox list.
|
||||||
*/
|
*/
|
||||||
private void loadAccounts() {
|
private void loadAccountMailboxInfo(final long accountId, final long mailboxId) {
|
||||||
mLoaderManager.initLoader(LOADER_ID_ACCOUNT_LIST, null,
|
mLoaderManager.restartLoader(LOADER_ID_ACCOUNT_LIST, null,
|
||||||
new LoaderCallbacks<Cursor>() {
|
new LoaderCallbacks<Cursor>() {
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
return AccountSelectorAdapter.createLoader(mContext, mCallback.getUIAccountId());
|
return AccountSelectorAdapter.createLoader(mContext, accountId, mailboxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||||
mAccountCursor = (AccountSelectorAdapter.CursorWithExtras) data;
|
mCursor = (AccountSelectorAdapter.CursorWithExtras) data;
|
||||||
updateAccountList();
|
updateTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaderReset(Loader<Cursor> loader) {
|
public void onLoaderReset(Loader<Cursor> loader) {
|
||||||
mAccountCursor = null;
|
mCursor = null;
|
||||||
updateAccountList();
|
updateTitle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the LOADER_ID_ACCOUNT_LIST loader loads the data. Update the account spinner
|
* Update the "title" part.
|
||||||
* on the action bar.
|
|
||||||
*/
|
*/
|
||||||
private void updateAccountList() {
|
private void updateTitle() {
|
||||||
mAccountsSelectorAdapter.swapCursor(mAccountCursor);
|
mAccountsSelectorAdapter.swapCursor(mCursor);
|
||||||
|
|
||||||
if (mSearchMode == MODE_SEARCH) {
|
if (mCursor == null) {
|
||||||
// In search mode, so we don't care about the account list - it'll get updated when
|
// Initial load not finished.
|
||||||
// it goes visible again.
|
mActionBarCustomView.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mActionBarCustomView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
final ActionBar ab = mActionBar;
|
if (mCursor.getAccountCount() == 0) {
|
||||||
if (mAccountCursor == null) {
|
|
||||||
// Cursor not ready or closed.
|
|
||||||
ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
|
|
||||||
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int count = mAccountCursor.getAccountCount() + mAccountCursor.getRecentMailboxCount();
|
|
||||||
if (count == 0) {
|
|
||||||
mCallback.onNoAccountsFound();
|
mCallback.onNoAccountsFound();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only one account, don't show the drop down.
|
if ((mCursor.getAccountId() != Account.NO_ACCOUNT) && !mCursor.accountExists()) {
|
||||||
int selectedPosition = mAccountCursor.getPosition(mCallback.getUIAccountId());
|
// Accoutn specified, but not exists. Switch to the default account.
|
||||||
if (count == 1) {
|
mCallback.onAccountSelected(Account.getDefaultAccountId(mContext));
|
||||||
// Show the account name as the title.
|
|
||||||
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
|
// STOPSHIP If in search mode, we should close the activity. Probably
|
||||||
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
// we should jsut call onSearchExit() instead?
|
||||||
if (selectedPosition >= 0) {
|
|
||||||
mAccountCursor.moveToPosition(selectedPosition);
|
|
||||||
ab.setTitle(AccountSelectorAdapter.getDisplayName(mAccountCursor));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the drop down list.
|
if (mSearchMode == MODE_SEARCH) {
|
||||||
if (ab.getNavigationMode() != ActionBar.NAVIGATION_MODE_LIST) {
|
// In search mode, so we don't care about the account list - it'll get updated when
|
||||||
ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
|
// it goes visible again.
|
||||||
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
mAccountSpinner.setVisibility(View.GONE);
|
||||||
ab.setListNavigationCallbacks(mAccountsSelectorAdapter, mActionBarNavigationCallback);
|
mSearchContainer.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Find the currently selected account, and select it.
|
|
||||||
if (selectedPosition >= 0) {
|
final int mTitleMode = mCallback.getTitleMode();
|
||||||
ab.setSelectedNavigationItem(selectedPosition);
|
|
||||||
|
// TODO Handle TITLE_MODE_MESSAGE_SUBJECT
|
||||||
|
|
||||||
|
// Account spinner visible.
|
||||||
|
mAccountSpinner.setVisibility(View.VISIBLE);
|
||||||
|
mSearchContainer.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
// Get mailbox name
|
||||||
|
final String mailboxName;
|
||||||
|
if (mTitleMode == Callback.TITLE_MODE_ACCOUNT_WITH_ALL_FOLDERS_LABEL) {
|
||||||
|
mailboxName = mAllFoldersLabel;
|
||||||
|
} else if (mTitleMode == Callback.TITLE_MODE_ACCOUNT_WITH_MAILBOX) {
|
||||||
|
mailboxName = mCursor.getMailboxDisplayName();
|
||||||
|
} else {
|
||||||
|
mailboxName = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private class ActionBarNavigationCallback implements ActionBar.OnNavigationListener {
|
if (TextUtils.isEmpty(mailboxName)) {
|
||||||
@Override
|
mAccountSpinnerLine1View.setText(mCursor.getAccountDisplayName());
|
||||||
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
|
|
||||||
if (mAccountsSelectorAdapter.isAccountItem(itemPosition)
|
// Only here we change the visibility of line 2, so line 1 will be vertically-centered.
|
||||||
&& itemId != mCallback.getUIAccountId()) {
|
mAccountSpinnerLine2View.setVisibility(View.GONE);
|
||||||
mCallback.onAccountSelected(itemId);
|
} else {
|
||||||
} else if (mAccountsSelectorAdapter.isMailboxItem(itemPosition)) {
|
mAccountSpinnerLine1View.setText(mailboxName);
|
||||||
mCallback.onMailboxSelected(itemId);
|
mAccountSpinnerLine2View.setVisibility(View.VISIBLE); // Make sure it's visible again.
|
||||||
// We need to update the selection, otherwise the user is unable to select the
|
mAccountSpinnerLine2View.setText(mCursor.getAccountDisplayName());
|
||||||
// recent folder a second time w/o first selecting another item in the spinner
|
|
||||||
int selectedPosition = mAccountsSelectorAdapter.getAccountPosition(itemPosition);
|
|
||||||
if (selectedPosition != AccountSelectorAdapter.UNKNOWN_POSITION) {
|
|
||||||
mActionBar.setSelectedNavigationItem(selectedPosition);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.i(Logging.LOG_TAG,
|
|
||||||
"Invalid type selected in ActionBarController at index " + itemPosition);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
mAccountSpinnerCountView.setText(UiUtilities.getMessageCountForUi(
|
||||||
|
mContext, mCursor.getMailboxMessageCount(), true));
|
||||||
|
|
||||||
private static final String[] MAILBOX_NAME_COUNT_PROJECTION = new String[] {
|
boolean spinnerEnabled = (mCursor.getAccountCount() + mCursor.getRecentMailboxCount()) > 1;
|
||||||
MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE,
|
|
||||||
MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
private void loadMailboxInfo(final long mailboxId) {
|
if (spinnerEnabled) {
|
||||||
clearMailboxInfo();
|
mAccountSpinner.setClickable(true);
|
||||||
if (mailboxId < 0) {
|
} else {
|
||||||
// TODO FIXME
|
mAccountSpinner.setClickable(false);
|
||||||
return; // Can't get combined mailbox name with this
|
// TODO There's nothing to select -- we should remove the spinner triangle.
|
||||||
|
// (The small triangle shown at the right bottom corner)
|
||||||
}
|
}
|
||||||
mLoaderManager.restartLoader(LOADER_ID_MAILBOX, null,
|
|
||||||
new LoaderCallbacks<Cursor>() {
|
|
||||||
@Override
|
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
|
||||||
return new ThrottlingCursorLoader(mContext,
|
|
||||||
ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
|
|
||||||
MAILBOX_NAME_COUNT_PROJECTION, null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
|
||||||
if (!cursor.moveToFirst()) {
|
|
||||||
clearMailboxInfo();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Update action bar
|
|
||||||
FolderProperties fp = FolderProperties.getInstance(mContext);
|
|
||||||
updateMailboxInfo(
|
|
||||||
fp.getDisplayName(cursor),
|
|
||||||
fp.getMessageCount(cursor)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoaderReset(Loader<Cursor> loader) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearMailboxInfo() {
|
|
||||||
updateMailboxInfo("", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMailboxInfo(String mailboxName, int count) {
|
|
||||||
mMailboxNameView.setText(mailboxName);
|
|
||||||
mUnreadCountView.setText(UiUtilities.getMessageCountForUi(mContext, count, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final SearchView.OnQueryTextListener mOnQueryText
|
private final SearchView.OnQueryTextListener mOnQueryText
|
||||||
|
@ -475,4 +459,44 @@ public class ActionBarController {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void onAccountSpinnerItemClicked(int position) {
|
||||||
|
if (mAccountsSelectorAdapter == null) { // just in case...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final long accountId = mAccountsSelectorAdapter.getAccountId(position);
|
||||||
|
|
||||||
|
if (mAccountsSelectorAdapter.isAccountItem(position)) {
|
||||||
|
mCallback.onAccountSelected(accountId);
|
||||||
|
} else if (mAccountsSelectorAdapter.isMailboxItem(position)) {
|
||||||
|
mCallback.onMailboxSelected(accountId,
|
||||||
|
mAccountsSelectorAdapter.getId(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on Spinner.DropdownPopup
|
||||||
|
private class AccountDropdownPopup extends ListPopupWindow {
|
||||||
|
public AccountDropdownPopup(Context context) {
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
setAnchorView(mAccountSpinner);
|
||||||
|
setModal(true);
|
||||||
|
setPromptPosition(POSITION_PROMPT_ABOVE);
|
||||||
|
setOnItemClickListener(new OnItemClickListener() {
|
||||||
|
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
||||||
|
onAccountSpinnerItemClicked(position);
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void show() {
|
||||||
|
setWidth(mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.account_spinner_dropdown_width));
|
||||||
|
setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
|
||||||
|
super.show();
|
||||||
|
// List view is instantiated in super.show(), so we need to do this after...
|
||||||
|
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,11 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
||||||
private long mParentMailboxId;
|
private long mParentMailboxId;
|
||||||
private long mHighlightedMailboxId;
|
private long mHighlightedMailboxId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Becomes {@code true} once we determine which mailbox to use as the parent.
|
||||||
|
*/
|
||||||
|
private boolean mParentDetermined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the mailbox that should be highlighted when the next cursor is loaded.
|
* ID of the mailbox that should be highlighted when the next cursor is loaded.
|
||||||
*/
|
*/
|
||||||
|
@ -551,7 +556,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
||||||
/**
|
/**
|
||||||
* @return {@code true} if top-level mailboxes are shown. {@code false} otherwise.
|
* @return {@code true} if top-level mailboxes are shown. {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isRoot() {
|
private boolean isRoot() {
|
||||||
return mParentMailboxId == Mailbox.NO_MAILBOX;
|
return mParentMailboxId == Mailbox.NO_MAILBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,6 +585,19 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the fragment is showing nested mailboxes and we can go one level up.
|
||||||
|
* {@code false} otherwise, meaning we're showing the top level mailboxes *OR*
|
||||||
|
* we're still loading initial data and we can't determine if we're going to show
|
||||||
|
* top-level or not.
|
||||||
|
*/
|
||||||
|
public boolean canNavigateUp() {
|
||||||
|
if (!mParentDetermined) {
|
||||||
|
return false; // We can't determine yet...
|
||||||
|
}
|
||||||
|
return !isRoot();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task to determine what parent mailbox ID/highlighted mailbox ID to use for the "UP"
|
* A task to determine what parent mailbox ID/highlighted mailbox ID to use for the "UP"
|
||||||
* navigation, given the current parent mailbox ID, the highlighted mailbox ID, and {@link
|
* navigation, given the current parent mailbox ID, the highlighted mailbox ID, and {@link
|
||||||
|
@ -781,6 +799,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
||||||
mListAdapter.swapCursor(null);
|
mListAdapter.swapCursor(null);
|
||||||
setListShown(false);
|
setListShown(false);
|
||||||
} else {
|
} else {
|
||||||
|
mParentDetermined = true; // Okay now we're sure which mailbox is the parent.
|
||||||
|
|
||||||
mListAdapter.swapCursor(cursor);
|
mListAdapter.swapCursor(cursor);
|
||||||
setListShown(true);
|
setListShown(true);
|
||||||
|
|
||||||
|
|
|
@ -431,12 +431,12 @@ abstract class UIControllerBase implements MailboxListFragment.Callback,
|
||||||
/**
|
/**
|
||||||
* Show the default view for the given account.
|
* Show the default view for the given account.
|
||||||
*
|
*
|
||||||
* No-op if the given account is already selected.
|
|
||||||
*
|
|
||||||
* @param accountId ID of the account to load. Can be {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
* @param accountId ID of the account to load. Can be {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
||||||
* Must never be {@link Account#NO_ACCOUNT}.
|
* Must never be {@link Account#NO_ACCOUNT}.
|
||||||
|
* @param forceShowInbox If {@code false} and the given account is already selected, do nothing.
|
||||||
|
* If {@code false}, we always change the view even if the account is selected.
|
||||||
*/
|
*/
|
||||||
public final void switchAccount(long accountId) {
|
public final void switchAccount(long accountId, boolean forceShowInbox) {
|
||||||
|
|
||||||
if (Account.isSecurityHold(mActivity, accountId)) {
|
if (Account.isSecurityHold(mActivity, accountId)) {
|
||||||
ActivityHelper.showSecurityHoldDialog(mActivity, accountId);
|
ActivityHelper.showSecurityHoldDialog(mActivity, accountId);
|
||||||
|
@ -444,7 +444,7 @@ abstract class UIControllerBase implements MailboxListFragment.Callback,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accountId == getUIAccountId()) {
|
if (accountId == getUIAccountId() && !forceShowInbox) {
|
||||||
// Do nothing if the account is already selected. Not even going back to the inbox.
|
// Do nothing if the account is already selected. Not even going back to the inbox.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,9 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
// MailboxListFragment.Callback
|
// MailboxListFragment.Callback
|
||||||
@Override
|
@Override
|
||||||
public void onAccountSelected(long accountId) {
|
public void onAccountSelected(long accountId) {
|
||||||
switchAccount(accountId);
|
// It's from combined view, so "forceShowInbox" doesn't really matter.
|
||||||
|
// (We're always switching accounts.)
|
||||||
|
switchAccount(accountId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MailboxListFragment.Callback
|
// MailboxListFragment.Callback
|
||||||
|
@ -94,7 +96,7 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
// MessageListFragment.Callback
|
// MessageListFragment.Callback
|
||||||
@Override
|
@Override
|
||||||
public void onMailboxNotFound() {
|
public void onMailboxNotFound() {
|
||||||
switchAccount(getUIAccountId());
|
switchAccount(getUIAccountId(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageListFragment.Callback
|
// MessageListFragment.Callback
|
||||||
|
@ -202,15 +204,26 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
// This is all temporary as we'll have a different action bar controller for 1-pane.
|
// This is all temporary as we'll have a different action bar controller for 1-pane.
|
||||||
private class ActionBarControllerCallback implements ActionBarController.Callback {
|
private class ActionBarControllerCallback implements ActionBarController.Callback {
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldShowMailboxName() {
|
public int getTitleMode() {
|
||||||
return false; // no mailbox name/unread count.
|
if (isMailboxListInstalled()) {
|
||||||
|
return TITLE_MODE_ACCOUNT_WITH_ALL_FOLDERS_LABEL;
|
||||||
|
}
|
||||||
|
// TODO Return TITLE_MODE_MESSAGE_SUBJECT if isMessageViewInstalled()
|
||||||
|
return TITLE_MODE_ACCOUNT_WITH_MAILBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMessageSubject() {
|
||||||
|
if (isMessageViewInstalled()) {
|
||||||
|
return "TODO: Return current message subject here";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldShowUp() {
|
public boolean shouldShowUp() {
|
||||||
return isMessageViewInstalled()
|
return isMessageViewInstalled()
|
||||||
|| (isMailboxListInstalled() && !getMailboxListFragment().isRoot());
|
|| (isMailboxListInstalled() && getMailboxListFragment().canNavigateUp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -224,11 +237,11 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMailboxSelected(long mailboxId) {
|
public void onMailboxSelected(long accountId, long mailboxId) {
|
||||||
if (mailboxId == Mailbox.NO_MAILBOX) {
|
if (mailboxId == Mailbox.NO_MAILBOX) {
|
||||||
showAllMailboxes();
|
showAllMailboxes();
|
||||||
} else {
|
} else {
|
||||||
openMailbox(getUIAccountId(), mailboxId);
|
openMailbox(accountId, mailboxId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +252,7 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccountSelected(long accountId) {
|
public void onAccountSelected(long accountId) {
|
||||||
switchAccount(accountId);
|
switchAccount(accountId, true); // Always go to inbox
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -434,7 +447,8 @@ class UIControllerOnePane extends UIControllerBase {
|
||||||
*/
|
*/
|
||||||
private void commitFragmentTransaction(FragmentTransaction ft) {
|
private void commitFragmentTransaction(FragmentTransaction ft) {
|
||||||
if (!ft.isEmpty()) {
|
if (!ft.isEmpty()) {
|
||||||
ft.commit();
|
// STOPSHIP Don't use AllowingStateLoss. See b/4519430
|
||||||
|
ft.commitAllowingStateLoss();
|
||||||
mFragmentManager.executePendingTransactions();
|
mFragmentManager.executePendingTransactions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,7 @@ import java.util.Set;
|
||||||
* so that we can easily switch between synchronous and asynchronous transactions.
|
* so that we can easily switch between synchronous and asynchronous transactions.
|
||||||
*/
|
*/
|
||||||
class UIControllerTwoPane extends UIControllerBase implements
|
class UIControllerTwoPane extends UIControllerBase implements
|
||||||
ThreePaneLayout.Callback,
|
ThreePaneLayout.Callback {
|
||||||
MailboxListFragment.Callback,
|
|
||||||
MessageListFragment.Callback,
|
|
||||||
MessageViewFragment.Callback {
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int MAILBOX_REFRESH_MIN_INTERVAL = 30 * 1000; // in milliseconds
|
static final int MAILBOX_REFRESH_MIN_INTERVAL = 30 * 1000; // in milliseconds
|
||||||
|
|
||||||
|
@ -75,8 +72,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
// ThreePaneLayoutCallback
|
// ThreePaneLayoutCallback
|
||||||
@Override
|
@Override
|
||||||
public void onVisiblePanesChanged(int previousVisiblePanes) {
|
public void onVisiblePanesChanged(int previousVisiblePanes) {
|
||||||
refreshActionBar();
|
|
||||||
|
|
||||||
// If the right pane is gone, remove the message view.
|
// If the right pane is gone, remove the message view.
|
||||||
final int visiblePanes = mThreePane.getVisiblePanes();
|
final int visiblePanes = mThreePane.getVisiblePanes();
|
||||||
|
|
||||||
|
@ -89,6 +84,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
if (isMessageListInstalled()) {
|
if (isMessageListInstalled()) {
|
||||||
getMessageListFragment().onHidden((visiblePanes & ThreePaneLayout.PANE_MIDDLE) == 0);
|
getMessageListFragment().onHidden((visiblePanes & ThreePaneLayout.PANE_MIDDLE) == 0);
|
||||||
}
|
}
|
||||||
|
refreshActionBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MailboxListFragment$Callback
|
// MailboxListFragment$Callback
|
||||||
|
@ -103,7 +99,9 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
// MailboxListFragment$Callback
|
// MailboxListFragment$Callback
|
||||||
@Override
|
@Override
|
||||||
public void onAccountSelected(long accountId) {
|
public void onAccountSelected(long accountId) {
|
||||||
switchAccount(accountId);
|
// It's from combined view, so "forceShowInbox" doesn't really matter.
|
||||||
|
// (We're always switching accounts.)
|
||||||
|
switchAccount(accountId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MailboxListFragment$Callback
|
// MailboxListFragment$Callback
|
||||||
|
@ -427,7 +425,8 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
Log.d(Logging.LOG_TAG, this + " commitFragmentTransaction: " + ft);
|
Log.d(Logging.LOG_TAG, this + " commitFragmentTransaction: " + ft);
|
||||||
}
|
}
|
||||||
if (!ft.isEmpty()) {
|
if (!ft.isEmpty()) {
|
||||||
ft.commit();
|
// STOPSHIP Don't use AllowingStateLoss. See b/4519430
|
||||||
|
ft.commitAllowingStateLoss();
|
||||||
mFragmentManager.executePendingTransactions();
|
mFragmentManager.executePendingTransactions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -818,12 +817,12 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccountSelected(long accountId) {
|
public void onAccountSelected(long accountId) {
|
||||||
switchAccount(accountId);
|
switchAccount(accountId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMailboxSelected(long mailboxId) {
|
public void onMailboxSelected(long accountId, long mailboxId) {
|
||||||
openMailbox(getUIAccountId(), mailboxId);
|
openMailbox(accountId, mailboxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -833,9 +832,32 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldShowMailboxName() {
|
public int getTitleMode() {
|
||||||
// Show when the left pane is hidden.
|
final int visiblePanes = mThreePane.getVisiblePanes();
|
||||||
return (mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_LEFT) == 0;
|
if ((mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_LEFT) != 0) {
|
||||||
|
// Mailbox list visible
|
||||||
|
return TITLE_MODE_ACCOUNT_NAME_ONLY;
|
||||||
|
}
|
||||||
|
if ((mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_MIDDLE) != 0) {
|
||||||
|
// Message list + message view
|
||||||
|
return TITLE_MODE_ACCOUNT_WITH_MAILBOX;
|
||||||
|
}
|
||||||
|
if ((mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_RIGHT) != 0) {
|
||||||
|
// Message view only (message list collapsed)
|
||||||
|
// TODO return TITLE_MODE_MESSAGE_SUBJECT
|
||||||
|
return TITLE_MODE_ACCOUNT_WITH_MAILBOX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shouldn't happen, but just in case
|
||||||
|
return TITLE_MODE_ACCOUNT_NAME_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessageSubject() {
|
||||||
|
if (isMessageViewInstalled()) {
|
||||||
|
return "TODO: Return current message subject here";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -843,7 +865,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
||||||
final int visiblePanes = mThreePane.getVisiblePanes();
|
final int visiblePanes = mThreePane.getVisiblePanes();
|
||||||
final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
|
final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
|
||||||
return leftPaneHidden
|
return leftPaneHidden
|
||||||
|| (isMailboxListInstalled() && !getMailboxListFragment().isRoot());
|
|| (isMailboxListInstalled() && getMailboxListFragment().canNavigateUp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class AccountSelectorAdapterAccountsLoaderTest extends LoaderTestCase {
|
||||||
{
|
{
|
||||||
// Only 1 account -- no combined view row.
|
// Only 1 account -- no combined view row.
|
||||||
Loader<Cursor> l = new AccountSelectorAdapter.AccountsLoader(mProviderContext, 0L,
|
Loader<Cursor> l = new AccountSelectorAdapter.AccountsLoader(mProviderContext, 0L,
|
||||||
true);
|
0L, true);
|
||||||
AccountSelectorAdapter.CursorWithExtras result =
|
AccountSelectorAdapter.CursorWithExtras result =
|
||||||
(AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l);
|
(AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l);
|
||||||
assertEquals(1, result.getAccountCount());
|
assertEquals(1, result.getAccountCount());
|
||||||
|
@ -64,7 +64,7 @@ public class AccountSelectorAdapterAccountsLoaderTest extends LoaderTestCase {
|
||||||
{
|
{
|
||||||
// 2 accounts -- with combined view row, so returns 3 account rows.
|
// 2 accounts -- with combined view row, so returns 3 account rows.
|
||||||
Loader<Cursor> l = new AccountSelectorAdapter.AccountsLoader(mProviderContext, 0L,
|
Loader<Cursor> l = new AccountSelectorAdapter.AccountsLoader(mProviderContext, 0L,
|
||||||
true);
|
0L, true);
|
||||||
AccountSelectorAdapter.CursorWithExtras result =
|
AccountSelectorAdapter.CursorWithExtras result =
|
||||||
(AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l);
|
(AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l);
|
||||||
assertEquals(3, result.getAccountCount());
|
assertEquals(3, result.getAccountCount());
|
||||||
|
|
Loading…
Reference in New Issue