Merge "Implement 1-pane navigation."
This commit is contained in:
commit
03b863d68e
|
@ -39,6 +39,17 @@
|
|||
android:icon="@drawable/ic_menu_refresh_holo_light"
|
||||
android:showAsAction="ifRoom"
|
||||
/>
|
||||
<!--
|
||||
STOPSHIP "Show all folders" should be in the account spinner, not here.
|
||||
It's temporary UI until we get the ICS style account spinner.
|
||||
-->
|
||||
<item
|
||||
android:id="@+id/show_all_folders"
|
||||
android:orderInCategory="400"
|
||||
android:title="@string/mailbox_list_account_selector_show_all_folders"
|
||||
android:showAsAction="ifRoom"
|
||||
android:visible="false"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/account_settings"
|
||||
android:orderInCategory="2000"
|
||||
|
|
|
@ -272,6 +272,9 @@
|
|||
<!-- Label shown in the account selector to select "Combined view", which contains
|
||||
Combined Inbox, Combined Outbox, etc. [CHAR LIMIT=30] -->
|
||||
<string name="mailbox_list_account_selector_combined_view">Combined view</string>
|
||||
<!-- Label shown in the account/mailbox selector to switch to the show all the top-level
|
||||
mailboxes. [CHAR LIMIT=30] -->
|
||||
<string name="mailbox_list_account_selector_show_all_folders">Show all folders</string>
|
||||
|
||||
<!-- Appears at the bottom of list of messages; user selects to load more messages from that folder. -->
|
||||
<string name="message_list_load_more_messages_action">Load more messages</string>
|
||||
|
|
|
@ -58,7 +58,7 @@ import java.util.ArrayList;
|
|||
* Because this activity is device agnostic, so most of the UI aren't owned by this, but by
|
||||
* the UIController.
|
||||
*/
|
||||
public class EmailActivity extends Activity implements View.OnClickListener {
|
||||
public class EmailActivity extends Activity implements View.OnClickListener, FragmentInstallable {
|
||||
private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
|
||||
private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID";
|
||||
private static final String EXTRA_MESSAGE_ID = "MESSAGE_ID";
|
||||
|
@ -196,9 +196,6 @@ public class EmailActivity extends Activity implements View.OnClickListener {
|
|||
int errorBannerHeight = getResources().getDimensionPixelSize(R.dimen.error_message_height);
|
||||
mErrorBanner = new BannerController(this, errorMessage, errorBannerHeight);
|
||||
|
||||
// Install restored fragments.
|
||||
mUIController.installRestoredFragments();
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mUIController.restoreInstanceState(savedInstanceState);
|
||||
} else {
|
||||
|
@ -233,12 +230,11 @@ public class EmailActivity extends Activity implements View.OnClickListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment fragment) {
|
||||
public void onInstallFragment(Fragment fragment) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " onAttachFragment fragment=" + fragment);
|
||||
Log.d(Logging.LOG_TAG, this + " onInstallFragment fragment=" + fragment);
|
||||
}
|
||||
super.onAttachFragment(fragment);
|
||||
mUIController.onAttachFragment(fragment);
|
||||
mUIController.onInstallFragment(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.email.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
|
||||
/**
|
||||
* Interface for {@link Activity} that can "install" fragments.
|
||||
*/
|
||||
public interface FragmentInstallable {
|
||||
/**
|
||||
* Called when a {@link Fragment} wants to be installed to the host activity.
|
||||
*
|
||||
* Fragments which use this MUST call this from {@link Fragment#onActivityCreated} using
|
||||
* {@link UiUtilities#installFragment}.
|
||||
*
|
||||
* This means a host {@link Activity} can safely assume a passed {@link Fragment} is already
|
||||
* created.
|
||||
*/
|
||||
public void onInstallFragment(Fragment fragment);
|
||||
}
|
|
@ -463,6 +463,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
lv.setOnDragListener(this);
|
||||
|
||||
startLoading(mParentMailboxId, mHighlightedMailboxId);
|
||||
|
||||
UiUtilities.installFragment(this);
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
|
|
|
@ -394,6 +394,8 @@ public class MessageListFragment extends ListFragment
|
|||
}
|
||||
|
||||
startLoading();
|
||||
|
||||
UiUtilities.installFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,6 +47,8 @@ import android.widget.ImageView;
|
|||
public class MessageViewFragment extends MessageViewFragmentBase
|
||||
implements CheckBox.OnCheckedChangeListener, MoveMessageToDialog.Callback {
|
||||
/** Argument name(s) */
|
||||
private static final String ARG_OPENER_ACCOUNT_ID = "accountId";
|
||||
private static final String ARG_OPENER_MAILBOX_ID = "mailboxId";
|
||||
private static final String ARG_MESSAGE_ID = "messageId";
|
||||
|
||||
private ImageView mFavoriteIcon;
|
||||
|
@ -125,13 +127,33 @@ public class MessageViewFragment extends MessageViewFragmentBase
|
|||
* Create a new instance with initialization parameters.
|
||||
*
|
||||
* This fragment should be created only with this method. (Arguments should always be set.)
|
||||
*
|
||||
* @param openerAccountId account ID that's used in the UI that opened this fragment.
|
||||
* The primary use is for the back navigation to determine which mailbox to show.
|
||||
*
|
||||
* Note this is not necessarily the same ID as the actual account ID for the message.
|
||||
* If a message is opened on the combined view, the caller probably want to pass
|
||||
* {@link Account#ACCOUNT_ID_COMBINED_VIEW} so that back will navigate to the
|
||||
* combined view.
|
||||
*
|
||||
* @param openerMailboxId mailbox ID that's used in the UI that opened this fragment.
|
||||
* The primary use is for the back navigation to determine which mailbox to show.
|
||||
*
|
||||
* Note this is not necessarily the same ID as the actual mailbox ID for the message.
|
||||
* If a message is opened on the combined view, the caller probably want to pass
|
||||
* a combined mailbox ID so that back will navigate to it.
|
||||
*
|
||||
* @param messageId ID of the message to open
|
||||
*/
|
||||
public static MessageViewFragment newInstance(long messageId) {
|
||||
if (messageId == -1) {
|
||||
public static MessageViewFragment newInstance(long openerAccountId, long openerMailboxId,
|
||||
long messageId) {
|
||||
if (messageId == Message.NO_MESSAGE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final MessageViewFragment instance = new MessageViewFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putLong(ARG_OPENER_ACCOUNT_ID, openerAccountId);
|
||||
args.putLong(ARG_OPENER_MAILBOX_ID, openerMailboxId);
|
||||
args.putLong(ARG_MESSAGE_ID, messageId);
|
||||
instance.setArguments(args);
|
||||
return instance;
|
||||
|
@ -144,10 +166,14 @@ public class MessageViewFragment extends MessageViewFragmentBase
|
|||
* constructs, this <em>must</em> be considered immutable.
|
||||
*/
|
||||
private Long mImmutableMessageId;
|
||||
private Long mImmutableOpenerAccountId;
|
||||
private Long mImmutableOpenerMailboxId;
|
||||
|
||||
private void initializeArgCache() {
|
||||
if (mImmutableMessageId != null) return;
|
||||
mImmutableMessageId = getArguments().getLong(ARG_MESSAGE_ID);
|
||||
mImmutableOpenerAccountId = getArguments().getLong(ARG_OPENER_ACCOUNT_ID);
|
||||
mImmutableOpenerMailboxId = getArguments().getLong(ARG_OPENER_MAILBOX_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,6 +184,22 @@ public class MessageViewFragment extends MessageViewFragmentBase
|
|||
return mImmutableMessageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the account ID passed to {@link #newInstance}. Safe to call even before onCreate.
|
||||
*/
|
||||
public long getOpenerAccountId() {
|
||||
initializeArgCache();
|
||||
return mImmutableOpenerAccountId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mailbox ID passed to {@link #newInstance}. Safe to call even before onCreate.
|
||||
*/
|
||||
public long getOpenerMailboxId() {
|
||||
initializeArgCache();
|
||||
return mImmutableOpenerMailboxId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
|
@ -341,6 +341,8 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
|
|||
|
||||
resetView();
|
||||
new LoadMessageTask(true).executeParallel();
|
||||
|
||||
UiUtilities.installFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,28 +26,24 @@ import com.android.emailcommon.provider.EmailContent.Message;
|
|||
import com.android.emailcommon.provider.Mailbox;
|
||||
import com.android.emailcommon.utility.EmailAsyncTask;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Base class for the UI controller.
|
||||
*
|
||||
* Note: Always use {@link #commitFragmentTransaction} to operate fragment transactions,
|
||||
* so that we can easily switch between synchronous and asynchronous transactions.
|
||||
*/
|
||||
abstract class UIControllerBase {
|
||||
protected static final String BUNDLE_KEY_ACCOUNT_ID = "UIController.state.account_id";
|
||||
protected static final String BUNDLE_KEY_MAILBOX_ID = "UIController.state.mailbox_id";
|
||||
protected static final String BUNDLE_KEY_MESSAGE_ID = "UIController.state.message_id";
|
||||
abstract class UIControllerBase implements MailboxListFragment.Callback,
|
||||
MessageListFragment.Callback, MessageViewFragment.Callback {
|
||||
protected static final String BUNDLE_KEY_RESUME_INBOX_LOOKUP
|
||||
= "UIController.state.resumeInboxLookup";
|
||||
protected static final String BUNDLE_KEY_INBOX_LOOKUP_ACCOUNT_ID
|
||||
|
@ -56,26 +52,15 @@ abstract class UIControllerBase {
|
|||
/** The owner activity */
|
||||
final EmailActivity mActivity;
|
||||
|
||||
private final ActionBarController mActionBarController;
|
||||
|
||||
final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
|
||||
|
||||
final RefreshManager mRefreshManager;
|
||||
|
||||
/**
|
||||
* List of fragments that are restored by the framework while the activity is being re-created
|
||||
* for configuration changes (e.g. screen rotation). We'll install them later when the activity
|
||||
* is created in {@link #installRestoredFragments()}.
|
||||
*/
|
||||
private final ArrayList<Fragment> mRestoredFragments = new ArrayList<Fragment>();
|
||||
|
||||
/** {@code true} if the activity is resumed. */
|
||||
private boolean mResumed;
|
||||
|
||||
/**
|
||||
* Whether fragment installation should be hold.
|
||||
* We hold installing fragments until {@link #installRestoredFragments()} is called.
|
||||
*/
|
||||
private boolean mHoldFragmentInstallation = true;
|
||||
|
||||
/**
|
||||
* Use to find Inbox. This should only run while the activity is resumed, because otherwise
|
||||
* we may not be able to perform fragment transactions when we get a callback.
|
||||
|
@ -96,34 +81,47 @@ abstract class UIControllerBase {
|
|||
*/
|
||||
private boolean mResumeInboxLookup;
|
||||
|
||||
/**
|
||||
* Fragments that are installed.
|
||||
*
|
||||
* A fragment is installed when:
|
||||
* - it is attached to the activity
|
||||
* - the parent activity is created
|
||||
* - and it is not scheduled to be removed.
|
||||
*
|
||||
* We set callbacks to fragments only when they are installed.
|
||||
*/
|
||||
private MailboxListFragment mMailboxListFragment;
|
||||
private MessageListFragment mMessageListFragment;
|
||||
private MessageViewFragment mMessageViewFragment;
|
||||
|
||||
private final RefreshManager.Listener mRefreshListener
|
||||
= new RefreshManager.Listener() {
|
||||
@Override
|
||||
public void onMessagingError(final long accountId, long mailboxId, final String message) {
|
||||
updateRefreshProgress();
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshStatusChanged(long accountId, long mailboxId) {
|
||||
updateRefreshProgress();
|
||||
refreshActionBar();
|
||||
}
|
||||
};
|
||||
|
||||
public UIControllerBase(EmailActivity activity) {
|
||||
mActivity = activity;
|
||||
mRefreshManager = RefreshManager.getInstance(mActivity);
|
||||
mActionBarController = createActionBarController(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the base class to let a subclass create an {@link ActionBarController}.
|
||||
*/
|
||||
protected abstract ActionBarController createActionBarController(Activity activity);
|
||||
|
||||
/** @return the layout ID for the activity. */
|
||||
public abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* @return true if the UI controller currently can install fragments.
|
||||
*/
|
||||
protected final boolean isFragmentInstallable() {
|
||||
return !mHoldFragmentInstallation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called just after the activity sets up the content view. Used to initialize views.
|
||||
*
|
||||
|
@ -144,6 +142,7 @@ abstract class UIControllerBase {
|
|||
Log.d(Logging.LOG_TAG, this + " onActivityCreated");
|
||||
}
|
||||
mRefreshManager.registerListener(mRefreshListener);
|
||||
mActionBarController.onActivityCreated();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,30 +196,10 @@ abstract class UIControllerBase {
|
|||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " onActivityDestroy");
|
||||
}
|
||||
mHoldFragmentInstallation = true; // No more fragment installation.
|
||||
mRefreshManager.unregisterListener(mRefreshListener);
|
||||
mTaskTracker.cancellAllInterrupt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Install all the fragments kept in {@link #mRestoredFragments}.
|
||||
*
|
||||
* Must be called at the end of {@link EmailActivity#onCreate}.
|
||||
*/
|
||||
public final void installRestoredFragments() {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " installRestoredFragments");
|
||||
}
|
||||
|
||||
mHoldFragmentInstallation = false;
|
||||
|
||||
// Install all the fragments restored by the framework.
|
||||
for (Fragment fragment : mRestoredFragments) {
|
||||
installFragment(fragment);
|
||||
}
|
||||
mRestoredFragments.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the {@link android.app.Activity#onSaveInstanceState} callback.
|
||||
*/
|
||||
|
@ -244,24 +223,12 @@ abstract class UIControllerBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles the {@link android.app.Activity#onAttachFragment} callback.
|
||||
*
|
||||
* If the activity has already been created, we initialize the fragment here. Otherwise we
|
||||
* keep the fragment in {@link #mRestoredFragments} and initialize it after the activity's
|
||||
* onCreate.
|
||||
* Install a fragment. Must be caleld from the host activity's
|
||||
* {@link FragmentInstallable#onInstallFragment}.
|
||||
*/
|
||||
public final void onAttachFragment(Fragment fragment) {
|
||||
if (mHoldFragmentInstallation) {
|
||||
// Fragment being restored by the framework during the activity recreation.
|
||||
mRestoredFragments.add(fragment);
|
||||
return;
|
||||
}
|
||||
installFragment(fragment);
|
||||
}
|
||||
|
||||
private void installFragment(Fragment fragment) {
|
||||
public final void onInstallFragment(Fragment fragment) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " installFragment fragment=" + fragment);
|
||||
Log.d(Logging.LOG_TAG, this + " onInstallFragment fragment=" + fragment);
|
||||
}
|
||||
if (fragment instanceof MailboxListFragment) {
|
||||
installMailboxListFragment((MailboxListFragment) fragment);
|
||||
|
@ -270,15 +237,114 @@ abstract class UIControllerBase {
|
|||
} else if (fragment instanceof MessageViewFragment) {
|
||||
installMessageViewFragment((MessageViewFragment) fragment);
|
||||
} else {
|
||||
// Ignore -- uninteresting fragments such as dialogs.
|
||||
throw new IllegalArgumentException("Tried to install unknown fragment");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void installMailboxListFragment(MailboxListFragment fragment);
|
||||
/** Install fragment */
|
||||
protected void installMailboxListFragment(MailboxListFragment fragment) {
|
||||
mMailboxListFragment = fragment;
|
||||
mMailboxListFragment.setCallback(this);
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
protected abstract void installMessageListFragment(MessageListFragment fragment);
|
||||
/** Install fragment */
|
||||
protected void installMessageListFragment(MessageListFragment fragment) {
|
||||
mMessageListFragment = fragment;
|
||||
mMessageListFragment.setCallback(this);
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
protected abstract void installMessageViewFragment(MessageViewFragment fragment);
|
||||
/** Install fragment */
|
||||
protected void installMessageViewFragment(MessageViewFragment fragment) {
|
||||
mMessageViewFragment = fragment;
|
||||
mMessageViewFragment.setCallback(this);
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall - If the fragment is installed, remove it from the given
|
||||
* {@link FragmentTransaction} and also clears the callabck.
|
||||
*/
|
||||
protected FragmentTransaction uninstallMailboxListFragment(FragmentTransaction ft) {
|
||||
if (isMailboxListInstalled()) {
|
||||
onMailboxListFragmentUninstalled(mMailboxListFragment);
|
||||
ft.remove(mMailboxListFragment);
|
||||
mMailboxListFragment.setCallback(null);
|
||||
mMailboxListFragment = null;
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
/** Called when a {@link MailboxListFragment} is about to be uninstalled */
|
||||
protected void onMailboxListFragmentUninstalled(MailboxListFragment fragment) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall - If the fragment is installed, remove it from the given
|
||||
* {@link FragmentTransaction} and also clears the callabck.
|
||||
*/
|
||||
protected FragmentTransaction uninstallMessageListFragment(FragmentTransaction ft) {
|
||||
if (isMessageListInstalled()) {
|
||||
onMessageListFragmentUninstalled(mMessageListFragment);
|
||||
ft.remove(mMessageListFragment);
|
||||
mMessageListFragment.setCallback(null);
|
||||
mMessageListFragment = null;
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
/** Called when a {@link MessageListFragment} is about to be uninstalled */
|
||||
protected void onMessageListFragmentUninstalled(MessageListFragment fragment) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall - If the fragment is installed, remove it from the given
|
||||
* {@link FragmentTransaction} and also clears the callabck.
|
||||
*/
|
||||
protected FragmentTransaction uninstallMessageViewFragment(FragmentTransaction ft) {
|
||||
if (isMessageViewInstalled()) {
|
||||
onMessageViewFragmentUninstalled(mMessageViewFragment);
|
||||
ft.remove(mMessageViewFragment);
|
||||
mMessageViewFragment.setCallback(null);
|
||||
mMessageViewFragment = null;
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
/** Called when a {@link MessageViewFragment} is about to be uninstalled */
|
||||
protected void onMessageViewFragmentUninstalled(MessageViewFragment fragment) {
|
||||
}
|
||||
|
||||
/** @return true if a {@link MailboxListFragment} is installed. */
|
||||
protected final boolean isMailboxListInstalled() {
|
||||
return mMailboxListFragment != null;
|
||||
}
|
||||
|
||||
/** @return true if a {@link MessageListFragment} is installed. */
|
||||
protected final boolean isMessageListInstalled() {
|
||||
return mMessageListFragment != null;
|
||||
}
|
||||
|
||||
/** @return true if a {@link MessageViewFragment} is installed. */
|
||||
protected final boolean isMessageViewInstalled() {
|
||||
return mMessageViewFragment != null;
|
||||
}
|
||||
|
||||
/** @return the installed {@link MailboxListFragment} or null. */
|
||||
protected final MailboxListFragment getMailboxListFragment() {
|
||||
return mMailboxListFragment;
|
||||
}
|
||||
|
||||
/** @return the installed {@link MessageListFragment} or null. */
|
||||
protected final MessageListFragment getMessageListFragment() {
|
||||
return mMessageListFragment;
|
||||
}
|
||||
|
||||
/** @return the installed {@link MessageViewFragment} or null. */
|
||||
protected final MessageViewFragment getMessageViewFragment() {
|
||||
return mMessageViewFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a {@link FragmentTransaction}.
|
||||
|
@ -535,14 +601,13 @@ abstract class UIControllerBase {
|
|||
*/
|
||||
protected abstract boolean isRefreshEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Start/stop the "refresh" animation on the action bar according to the current refresh state.
|
||||
*
|
||||
* (We start the animation if {@link #isRefreshInProgress} returns true,
|
||||
* and stop otherwise.)
|
||||
* Refresh the action bar and menu items, including the "refreshing" icon.
|
||||
*/
|
||||
protected void updateRefreshProgress() {
|
||||
protected void refreshActionBar() {
|
||||
if (mActionBarController != null) {
|
||||
mActionBarController.refresh();
|
||||
}
|
||||
mActivity.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,21 @@ package com.android.email.activity;
|
|||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
import com.android.email.activity.MailboxFinder.Callback;
|
||||
import com.android.email.activity.setup.AccountSecurity;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.Message;
|
||||
import com.android.emailcommon.provider.Mailbox;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
|
||||
import android.app.FragmentManager;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -36,183 +41,179 @@ import java.util.Set;
|
|||
/**
|
||||
* UI Controller for non x-large devices. Supports a single-pane layout.
|
||||
*
|
||||
* STOPSHIP Everything in this class is 100% temporary at this point
|
||||
* - Navigation model is different from what it should be (whatever it'll be).
|
||||
* e.g. when the app is launched, we should show Inbox, not mailbox list.
|
||||
* One one-pane, multiple fragments can be installed at the same time, but only one of them
|
||||
* can be "visible" at a time. Others are in the back stack. Use {@link #isMailboxListVisible()},
|
||||
* {@link #isMessageListVisible()} and {@link #isMessageViewVisible()} to determine which is
|
||||
* visible.
|
||||
*
|
||||
* - It uses the two-pane action bar only so that we can change accounts
|
||||
* Note due to the asynchronous nature of the fragment transaction, there is a window when
|
||||
* there is no installed or visible fragments.
|
||||
*
|
||||
* TODO Use the back stack for the message list -> message view navigation, so that the list
|
||||
* position/selection will be restored on back.
|
||||
*
|
||||
* Major TODOs
|
||||
* - TODO Proper Navigation model, including retaining fragments to keep state such as the scroll
|
||||
* position and batch selection.
|
||||
* - TODO Nested folders
|
||||
* - TODO Newer/Older for message view with swipe!
|
||||
* - TODO Implement callbacks
|
||||
*/
|
||||
class UIControllerOnePane extends UIControllerBase {
|
||||
private ActionBarController mActionBarController;
|
||||
|
||||
/**
|
||||
* Current account/mailbox/message IDs.
|
||||
* Don't use them directly; use the accessors instead, as we might want to get them from the
|
||||
* topmost fragment in the future.
|
||||
*/
|
||||
private long mCurrentAccountId = Account.NO_ACCOUNT;
|
||||
private long mCurrentMailboxId = Mailbox.NO_MAILBOX;
|
||||
private long mCurrentMessageId = Message.NO_MESSAGE;
|
||||
|
||||
// TODO Newer/Older buttons not needed. Remove this.
|
||||
private MessageCommandButtonView mMessageCommandButtons;
|
||||
|
||||
private final MailboxListFragment.Callback mMailboxListFragmentCallback =
|
||||
new MailboxListFragment.Callback() {
|
||||
@Override
|
||||
public void onAccountSelected(long accountId) {
|
||||
switchAccount(accountId);
|
||||
// MailboxListFragment.Callback
|
||||
@Override
|
||||
public void onAccountSelected(long accountId) {
|
||||
switchAccount(accountId);
|
||||
}
|
||||
|
||||
// MailboxListFragment.Callback
|
||||
@Override
|
||||
public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
|
||||
}
|
||||
|
||||
// MailboxListFragment.Callback
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) {
|
||||
if (nestedNavigation) {
|
||||
return; // Nothing to do on 1-pane.
|
||||
}
|
||||
openMailbox(accountId, mailboxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
|
||||
// MailboxListFragment.Callback
|
||||
@Override
|
||||
public void onParentMailboxChanged() {
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onAdvancingOpAccepted(Set<Long> affectedMessages) {
|
||||
// Nothing to do on 1 pane.
|
||||
}
|
||||
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onEnterSelectionMode(boolean enter) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onListLoaded() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onMailboxNotFound() {
|
||||
open(getUIAccountId(), Mailbox.NO_MAILBOX, Message.NO_MESSAGE);
|
||||
}
|
||||
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onMessageOpen(
|
||||
long messageId, long messageMailboxId, long listMailboxId, int type) {
|
||||
if (type == MessageListFragment.Callback.TYPE_DRAFT) {
|
||||
MessageCompose.actionEditDraft(mActivity, messageId);
|
||||
} else {
|
||||
open(getUIAccountId(), getMailboxId(), messageId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) {
|
||||
if (nestedNavigation) {
|
||||
return; // Nothing to do on 1-pane.
|
||||
}
|
||||
openMailbox(accountId, mailboxId);
|
||||
}
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public boolean onDragStarted() {
|
||||
// No drag&drop on 1-pane
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParentMailboxChanged() {
|
||||
refreshActionBar();
|
||||
}
|
||||
};
|
||||
// MessageListFragment.Callback
|
||||
@Override
|
||||
public void onDragEnded() {
|
||||
// No drag&drop on 1-pane
|
||||
}
|
||||
|
||||
private final MessageListFragment.Callback mMessageListFragmentCallback =
|
||||
new MessageListFragment.Callback() {
|
||||
@Override
|
||||
public void onAdvancingOpAccepted(Set<Long> affectedMessages) {
|
||||
// Nothing to do on 1 pane.
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onForward() {
|
||||
MessageCompose.actionForward(mActivity, getMessageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterSelectionMode(boolean enter) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onReply() {
|
||||
MessageCompose.actionReply(mActivity, getMessageId(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListLoaded() {
|
||||
// TODO Auto-generated method stub
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onReplyAll() {
|
||||
MessageCompose.actionReply(mActivity, getMessageId(), true);
|
||||
}
|
||||
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onCalendarLinkClicked(long epochEventStartTime) {
|
||||
ActivityHelper.openCalendar(mActivity, epochEventStartTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxNotFound() {
|
||||
open(getUIAccountId(), Mailbox.NO_MAILBOX, Message.NO_MESSAGE);
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public boolean onUrlInMessageClicked(String url) {
|
||||
return ActivityHelper.openUrlInMessage(mActivity, url, getActualAccountId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageOpen(
|
||||
long messageId, long messageMailboxId, long listMailboxId, int type) {
|
||||
if (type == MessageListFragment.Callback.TYPE_DRAFT) {
|
||||
MessageCompose.actionEditDraft(mActivity, messageId);
|
||||
} else {
|
||||
open(getUIAccountId(), getMailboxId(), messageId);
|
||||
}
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onBeforeMessageGone() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDragStarted() {
|
||||
// No drag&drop on 1-pane
|
||||
return false;
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onMessageSetUnread() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnded() {
|
||||
// No drag&drop on 1-pane
|
||||
}
|
||||
};
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onRespondedToInvite(int response) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
private final MessageViewFragment.Callback mMessageViewFragmentCallback =
|
||||
new MessageViewFragment.Callback() {
|
||||
@Override
|
||||
public void onForward() {
|
||||
MessageCompose.actionForward(mActivity, getMessageId());
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onLoadMessageError(String errorMessage) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReply() {
|
||||
MessageCompose.actionReply(mActivity, getMessageId(), false);
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onLoadMessageFinished() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplyAll() {
|
||||
MessageCompose.actionReply(mActivity, getMessageId(), true);
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onLoadMessageStarted() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalendarLinkClicked(long epochEventStartTime) {
|
||||
ActivityHelper.openCalendar(mActivity, epochEventStartTime);
|
||||
}
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onMessageNotExists() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUrlInMessageClicked(String url) {
|
||||
return ActivityHelper.openUrlInMessage(mActivity, url, getActualAccountId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeMessageGone() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSetUnread() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRespondedToInvite(int response) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageError(String errorMessage) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageFinished() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageStarted() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotExists() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMessageShown() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
// MessageViewFragment.Callback
|
||||
@Override
|
||||
public void onMessageShown() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
// This is all temporary as we'll have a different action bar controller for 1-pane.
|
||||
private final ActionBarController.Callback mActionBarControllerCallback
|
||||
= new ActionBarController.Callback() {
|
||||
private class ActionBarControllerCallback implements ActionBarController.Callback {
|
||||
@Override
|
||||
public boolean shouldShowMailboxName() {
|
||||
return false; // no mailbox name/unread count.
|
||||
|
@ -230,8 +231,8 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
|
||||
@Override
|
||||
public boolean shouldShowUp() {
|
||||
// Always show the UP arrow.
|
||||
return true;
|
||||
return isMessageViewVisible()
|
||||
|| (isMailboxListVisible() && !getMailboxListFragment().isRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -254,37 +255,30 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
Welcome.actionStart(mActivity);
|
||||
mActivity.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public UIControllerOnePane(EmailActivity activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* At this point we use synchronous transactions.
|
||||
*/
|
||||
@Override
|
||||
protected void commitFragmentTransaction(FragmentTransaction ft) {
|
||||
super.commitFragmentTransaction(ft);
|
||||
mActivity.getFragmentManager().executePendingTransactions();
|
||||
protected ActionBarController createActionBarController(Activity activity) {
|
||||
|
||||
// For now, we just reuse the same action bar controller used for 2-pane.
|
||||
// We may change it later.
|
||||
|
||||
return new ActionBarController(activity, activity.getLoaderManager(),
|
||||
activity.getActionBar(), new ActionBarControllerCallback());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong(BUNDLE_KEY_ACCOUNT_ID, mCurrentAccountId);
|
||||
outState.putLong(BUNDLE_KEY_MAILBOX_ID, mCurrentMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_MESSAGE_ID, mCurrentMessageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreInstanceState(Bundle savedInstanceState) {
|
||||
super.restoreInstanceState(savedInstanceState);
|
||||
mCurrentAccountId = savedInstanceState.getLong(BUNDLE_KEY_ACCOUNT_ID, Account.NO_ACCOUNT);
|
||||
mCurrentMailboxId = savedInstanceState.getLong(BUNDLE_KEY_MAILBOX_ID, Mailbox.NO_MAILBOX);
|
||||
mCurrentMessageId = savedInstanceState.getLong(BUNDLE_KEY_MESSAGE_ID, Message.NO_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -295,8 +289,6 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
@Override
|
||||
public void onActivityViewReady() {
|
||||
super.onActivityViewReady();
|
||||
mActionBarController = new ActionBarController(mActivity, mActivity.getLoaderManager(),
|
||||
mActivity.getActionBar(), mActionBarControllerCallback);
|
||||
|
||||
mMessageCommandButtons = UiUtilities.getView(mActivity, R.id.message_command_buttons);
|
||||
mMessageCommandButtons.setCallback(new CommandButtonCallback());
|
||||
|
@ -305,7 +297,6 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
@Override
|
||||
public void onActivityCreated() {
|
||||
super.onActivityCreated();
|
||||
mActionBarController.onActivityCreated();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -314,76 +305,96 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
refreshActionBar();
|
||||
}
|
||||
|
||||
/** @return true if a {@link MailboxListFragment} is installed and visible. */
|
||||
private final boolean isMailboxListVisible() {
|
||||
return isMailboxListInstalled();
|
||||
}
|
||||
|
||||
/** @return true if a {@link MessageListFragment} is installed and visible. */
|
||||
private final boolean isMessageListVisible() {
|
||||
return isMessageListInstalled();
|
||||
}
|
||||
|
||||
/** @return true if a {@link MessageViewFragment} is installed and visible. */
|
||||
private final boolean isMessageViewVisible() {
|
||||
return isMessageViewInstalled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUIAccountId() {
|
||||
return mCurrentAccountId;
|
||||
// Get it from the visible fragment.
|
||||
if (isMailboxListVisible()) {
|
||||
return getMailboxListFragment().getAccountId();
|
||||
}
|
||||
if (isMessageListVisible()) {
|
||||
return getMessageListFragment().getAccountId();
|
||||
}
|
||||
if (isMessageViewVisible()) {
|
||||
return getMessageViewFragment().getOpenerAccountId();
|
||||
}
|
||||
return Account.NO_ACCOUNT;
|
||||
}
|
||||
|
||||
private long getMailboxId() {
|
||||
return mCurrentMailboxId;
|
||||
// Get it from the visible fragment.
|
||||
if (isMessageListVisible()) {
|
||||
return getMessageListFragment().getMailboxId();
|
||||
}
|
||||
if (isMessageViewVisible()) {
|
||||
return getMessageViewFragment().getOpenerMailboxId();
|
||||
}
|
||||
return Mailbox.NO_MAILBOX;
|
||||
}
|
||||
|
||||
private long getMessageId() {
|
||||
return mCurrentMessageId;
|
||||
// Get it from the visible fragment.
|
||||
if (isMessageViewVisible()) {
|
||||
return getMessageViewFragment().getMessageId();
|
||||
}
|
||||
return Message.NO_MESSAGE;
|
||||
}
|
||||
|
||||
private final MailboxFinder.Callback mInboxLookupCallback = new MailboxFinder.Callback() {
|
||||
@Override
|
||||
public void onMailboxFound(long accountId, long mailboxId) {
|
||||
// Inbox found.
|
||||
openMailbox(accountId, mailboxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountNotFound() {
|
||||
// Account removed?
|
||||
Welcome.actionStart(mActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxNotFound(long accountId) {
|
||||
// Inbox not found??
|
||||
Welcome.actionStart(mActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountSecurityHold(long accountId) {
|
||||
mActivity.startActivity(AccountSecurity.actionUpdateSecurityIntent(mActivity, accountId,
|
||||
true));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Callback getInboxLookupCallback() {
|
||||
// We don't call startInboxLookup in UIControllerOnePane, so shouldn't be called.
|
||||
throw new RuntimeException("SHOULD NOT BE CALLED"); // STOPSHIP
|
||||
}
|
||||
|
||||
private void refreshActionBar() {
|
||||
if (mActionBarController != null) {
|
||||
mActionBarController.refresh();
|
||||
}
|
||||
mActivity.invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private boolean isMailboxListVisible() {
|
||||
return (getMailboxId() == Mailbox.NO_MAILBOX);
|
||||
}
|
||||
|
||||
private boolean isMessageListVisible() {
|
||||
return (getMailboxId() != Mailbox.NO_MAILBOX) && (getMessageId() == Message.NO_MESSAGE);
|
||||
}
|
||||
|
||||
private boolean isMessageViewVisible() {
|
||||
return (getMailboxId() != Mailbox.NO_MAILBOX) && (getMessageId() != Message.NO_MESSAGE);
|
||||
return mInboxLookupCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed(boolean isSystemBackKey) {
|
||||
if (isMessageViewVisible()) {
|
||||
open(getUIAccountId(), getMailboxId(), Message.NO_MESSAGE);
|
||||
openMailbox(getMessageViewFragment().getOpenerAccountId(),
|
||||
getMessageViewFragment().getOpenerMailboxId());
|
||||
return true;
|
||||
} else if (isMessageListVisible()) {
|
||||
open(getUIAccountId(), Mailbox.NO_MAILBOX, Message.NO_MESSAGE);
|
||||
} else if (isMailboxListVisible() && getMailboxListFragment().navigateUp()) {
|
||||
return true;
|
||||
} else {
|
||||
// TODO Call MailboxListFragment.navigateUp().
|
||||
|
||||
// STOPSHIP Remove this and return false. This is so that the app can be closed
|
||||
// with the UP press. (usuful when the device doesn't have a HW back key.)
|
||||
mActivity.finish();
|
||||
return true;
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMailboxListFragment(MailboxListFragment fragment) {
|
||||
fragment.setCallback(mMailboxListFragmentCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMessageListFragment(MessageListFragment fragment) {
|
||||
fragment.setCallback(mMessageListFragmentCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMessageViewFragment(MessageViewFragment fragment) {
|
||||
fragment.setCallback(mMessageViewFragmentCallback);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -396,40 +407,63 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// !!! It's all temporary to make 1 pane UI (barely) usable !!!
|
||||
//
|
||||
// - Nested folders still doesn't work
|
||||
// - When opening a child view (e.g. message list -> message view), we should retain
|
||||
// the current fragment so that all the state (selection, scroll position, etc) will be
|
||||
// restored when back.
|
||||
|
||||
if ((getUIAccountId() == accountId) && (getMailboxId() == mailboxId)
|
||||
&& (getMessageId() == messageId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final FragmentManager fm = mActivity.getFragmentManager();
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
|
||||
if (messageId != Message.NO_MESSAGE) {
|
||||
ft.replace(R.id.fragment_placeholder, MessageViewFragment.newInstance(messageId));
|
||||
|
||||
showMessageView(accountId, mailboxId, messageId);
|
||||
} else if (mailboxId != Mailbox.NO_MAILBOX) {
|
||||
ft.replace(R.id.fragment_placeholder, MessageListFragment.newInstance(
|
||||
accountId, mailboxId));
|
||||
|
||||
showMessageList(accountId, mailboxId);
|
||||
} else {
|
||||
ft.replace(R.id.fragment_placeholder,
|
||||
MailboxListFragment.newInstance(accountId, Mailbox.NO_MAILBOX, false));
|
||||
// Mailbox not specified. Open Inbox or Combined Inbox.
|
||||
if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
showMessageList(accountId, Mailbox.QUERY_ALL_INBOXES);
|
||||
} else {
|
||||
startInboxLookup(accountId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentAccountId = accountId;
|
||||
mCurrentMailboxId = mailboxId;
|
||||
mCurrentMessageId = messageId;
|
||||
private void uninstallAllFragments(FragmentTransaction ft) {
|
||||
if (isMailboxListInstalled()) {
|
||||
uninstallMailboxListFragment(ft);
|
||||
}
|
||||
if (isMessageListInstalled()) {
|
||||
uninstallMessageListFragment(ft);
|
||||
}
|
||||
if (isMessageViewInstalled()) {
|
||||
uninstallMessageViewFragment(ft);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMailboxList(long accountId, long mailboxId) {
|
||||
showFragment(MailboxListFragment.newInstance(accountId, mailboxId, false));
|
||||
}
|
||||
|
||||
private void showMessageList(long accountId, long mailboxId) {
|
||||
showFragment(MessageListFragment.newInstance(accountId, mailboxId));
|
||||
}
|
||||
|
||||
private void showMessageView(long accountId, long mailboxId, long messageId) {
|
||||
showFragment(MessageViewFragment.newInstance(accountId, mailboxId, messageId));
|
||||
}
|
||||
|
||||
private void showFragment(Fragment fragment) {
|
||||
final FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
|
||||
uninstallAllFragments(ft);
|
||||
ft.add(R.id.fragment_placeholder, fragment);
|
||||
commitFragmentTransaction(ft);
|
||||
}
|
||||
|
||||
refreshActionBar();
|
||||
private void showAllMailboxes() {
|
||||
if (!isAccountSelected()) {
|
||||
return; // Can happen because of asyncronous fragment transactions.
|
||||
}
|
||||
// Don't use open(account, NO_MAILBOX, NO_MESSAGE). This is used to open the default
|
||||
// view, which is Inbox on the message list.
|
||||
showMailboxList(getUIAccountId(), Mailbox.NO_MAILBOX);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -495,4 +529,21 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
return mRefreshManager.isMailboxListRefreshing(getActualAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(MenuInflater inflater, Menu menu) {
|
||||
// STOPSHIP For temporary menu item which should be visible only on 1-pane.
|
||||
menu.findItem(R.id.show_all_folders).setVisible(true);
|
||||
return super.onPrepareOptionsMenu(inflater, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.show_all_folders: // STOPSHIP For temporary menu item
|
||||
showAllMailboxes();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,27 +54,9 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
@VisibleForTesting
|
||||
static final int INBOX_AUTO_REFRESH_MIN_INTERVAL = 10 * 1000; // in milliseconds
|
||||
|
||||
private ActionBarController mActionBarController;
|
||||
private final ActionBarControllerCallback mActionBarControllerCallback =
|
||||
new ActionBarControllerCallback();
|
||||
|
||||
// Other UI elements
|
||||
private ThreePaneLayout mThreePane;
|
||||
|
||||
/**
|
||||
* Fragments that are installed.
|
||||
*
|
||||
* A fragment is installed when:
|
||||
* - it is attached to the activity
|
||||
* - the parent activity is created
|
||||
* - and it is not scheduled to be removed.
|
||||
*
|
||||
* We set callbacks to fragments only when they are installed.
|
||||
*/
|
||||
private MailboxListFragment mMailboxListFragment;
|
||||
private MessageListFragment mMessageListFragment;
|
||||
private MessageViewFragment mMessageViewFragment;
|
||||
|
||||
private MessageCommandButtonView mMessageCommandButtons;
|
||||
|
||||
private MessageOrderManager mOrderManager;
|
||||
|
@ -100,12 +82,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
FragmentManager.enableDebugLogging(true);
|
||||
}
|
||||
|
||||
private void refreshActionBar() {
|
||||
if (mActionBarController != null) {
|
||||
mActionBarController.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutId() {
|
||||
return R.layout.email_activity_two_pane;
|
||||
|
@ -163,7 +139,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
}
|
||||
// Disable CAB when the message list is not visible.
|
||||
if (isMessageListInstalled()) {
|
||||
mMessageListFragment.onHidden((visiblePanes & ThreePaneLayout.PANE_MIDDLE) == 0);
|
||||
getMessageListFragment().onHidden((visiblePanes & ThreePaneLayout.PANE_MIDDLE) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,8 +353,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
@Override
|
||||
public void onActivityViewReady() {
|
||||
super.onActivityViewReady();
|
||||
mActionBarController = new ActionBarController(mActivity, mActivity.getLoaderManager(),
|
||||
mActivity.getActionBar(), mActionBarControllerCallback);
|
||||
|
||||
// Set up content
|
||||
mThreePane = (ThreePaneLayout) mActivity.findViewById(R.id.three_pane);
|
||||
|
@ -388,6 +362,12 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
mMessageCommandButtons.setCallback(new CommandButtonCallback());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionBarController createActionBarController(Activity activity) {
|
||||
return new ActionBarController(activity, activity.getLoaderManager(),
|
||||
activity.getActionBar(), new ActionBarControllerCallback());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the currently selected account ID, *or* {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
||||
*
|
||||
|
@ -395,7 +375,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
*/
|
||||
@Override
|
||||
public long getUIAccountId() {
|
||||
return isMailboxListInstalled() ? mMailboxListFragment.getAccountId()
|
||||
return isMailboxListInstalled() ? getMailboxListFragment().getAccountId()
|
||||
:Account.NO_ACCOUNT;
|
||||
}
|
||||
|
||||
|
@ -406,7 +386,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
* {@link #getMessageListMailboxId()}
|
||||
*/
|
||||
private long getMailboxListMailboxId() {
|
||||
return isMailboxListInstalled() ? mMailboxListFragment.getSelectedMailboxId()
|
||||
return isMailboxListInstalled() ? getMailboxListFragment().getSelectedMailboxId()
|
||||
: Mailbox.NO_MAILBOX;
|
||||
}
|
||||
|
||||
|
@ -417,7 +397,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
* {@link #getMessageListMailboxId()}
|
||||
*/
|
||||
private long getMessageListMailboxId() {
|
||||
return isMessageListInstalled() ? mMessageListFragment.getMailboxId()
|
||||
return isMessageListInstalled() ? getMessageListFragment().getMailboxId()
|
||||
: Message.NO_MESSAGE;
|
||||
}
|
||||
|
||||
|
@ -438,23 +418,10 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
}
|
||||
|
||||
private long getMessageId() {
|
||||
return isMessageViewInstalled() ? mMessageViewFragment.getMessageId()
|
||||
return isMessageViewInstalled() ? getMessageViewFragment().getMessageId()
|
||||
: Message.NO_MESSAGE;
|
||||
}
|
||||
|
||||
private boolean isMailboxListInstalled() {
|
||||
return mMailboxListFragment != null;
|
||||
}
|
||||
|
||||
private boolean isMessageListInstalled() {
|
||||
return mMessageListFragment != null;
|
||||
}
|
||||
|
||||
private boolean isMessageViewInstalled() {
|
||||
return mMessageViewFragment != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if refresh is in progress for the current mailbox.
|
||||
*/
|
||||
|
@ -481,7 +448,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
@Override
|
||||
public void onActivityCreated() {
|
||||
super.onActivityCreated();
|
||||
mActionBarController.onActivityCreated();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -536,67 +502,28 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMailboxListFragment(MailboxListFragment fragment) {
|
||||
mMailboxListFragment = fragment;
|
||||
mMailboxListFragment.setCallback(this);
|
||||
|
||||
// Update action bar / menu
|
||||
updateRefreshProgress();
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMessageListFragment(MessageListFragment fragment) {
|
||||
mMessageListFragment = fragment;
|
||||
mMessageListFragment.setCallback(this);
|
||||
super.installMessageListFragment(fragment);
|
||||
|
||||
if (isMailboxListInstalled()) {
|
||||
mMailboxListFragment.setHighlightedMailbox(mMessageListFragment.getMailboxId());
|
||||
getMailboxListFragment().setHighlightedMailbox(fragment.getMailboxId());
|
||||
}
|
||||
|
||||
// Update action bar / menu
|
||||
updateRefreshProgress();
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installMessageViewFragment(MessageViewFragment fragment) {
|
||||
mMessageViewFragment = fragment;
|
||||
mMessageViewFragment.setCallback(this);
|
||||
super.installMessageViewFragment(fragment);
|
||||
|
||||
if (isMessageListInstalled()) {
|
||||
mMessageListFragment.setSelectedMessage(mMessageViewFragment.getMessageId());
|
||||
getMessageListFragment().setSelectedMessage(fragment.getMessageId());
|
||||
}
|
||||
}
|
||||
|
||||
private FragmentTransaction uninstallMailboxListFragment(FragmentTransaction ft) {
|
||||
if (isMailboxListInstalled()) {
|
||||
ft.remove(mMailboxListFragment);
|
||||
mMailboxListFragment.setCallback(null);
|
||||
mMailboxListFragment = null;
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
private FragmentTransaction uninstallMessageListFragment(FragmentTransaction ft) {
|
||||
if (isMessageListInstalled()) {
|
||||
ft.remove(mMessageListFragment);
|
||||
mMessageListFragment.setCallback(null);
|
||||
mMessageListFragment = null;
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
private FragmentTransaction uninstallMessageViewFragment(FragmentTransaction ft) {
|
||||
if (isMessageViewInstalled()) {
|
||||
ft.remove(mMessageViewFragment);
|
||||
mMessageViewFragment.setCallback(null);
|
||||
mMessageViewFragment = null;
|
||||
// Don't need it when there's no message view.
|
||||
stopMessageOrderManager();
|
||||
}
|
||||
return ft;
|
||||
@Override
|
||||
protected void onMessageViewFragmentUninstalled(MessageViewFragment fragment) {
|
||||
// Don't need it when there's no message view.
|
||||
stopMessageOrderManager();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -638,20 +565,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
commitFragmentTransaction(ft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-fragment transaction check.
|
||||
*
|
||||
* @throw IllegalStateException if updateXxx methods can't be called in the current state.
|
||||
*/
|
||||
private void preFragmentTransactionCheck() {
|
||||
if (!isFragmentInstallable()) {
|
||||
// Code assumes mMailboxListFragment/etc are set right within the
|
||||
// commitFragmentTransaction() call (because we use synchronous transaction),
|
||||
// so updateXxx() can't be called if fragments are not installable yet.
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given account and optionally selects the given mailbox and message. If the
|
||||
* specified account is already selected, no actions will be performed unless
|
||||
|
@ -669,12 +582,10 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
Log.d(Logging.LOG_TAG, this + " updateMailboxList accountId=" + accountId
|
||||
+ " mailboxId=" + mailboxId);
|
||||
}
|
||||
preFragmentTransactionCheck();
|
||||
if (accountId == Account.NO_ACCOUNT) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
|
||||
if ((getUIAccountId() != accountId) || (getMailboxListMailboxId() != mailboxId)) {
|
||||
uninstallMailboxListFragment(ft);
|
||||
ft.add(mThreePane.getLeftPaneId(),
|
||||
|
@ -721,7 +632,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " updateMessageList mMailboxId=" + mailboxId);
|
||||
}
|
||||
preFragmentTransactionCheck();
|
||||
if (mailboxId == Mailbox.NO_MAILBOX) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -758,7 +668,6 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " updateMessageView messageId=" + messageId);
|
||||
}
|
||||
preFragmentTransactionCheck();
|
||||
if (messageId == Message.NO_MESSAGE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -768,7 +677,9 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
}
|
||||
|
||||
uninstallMessageViewFragment(ft);
|
||||
ft.add(mThreePane.getRightPaneId(), MessageViewFragment.newInstance(messageId));
|
||||
|
||||
ft.add(mThreePane.getRightPaneId(), MessageViewFragment.newInstance(
|
||||
getUIAccountId(), getMessageListMailboxId(), messageId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -786,8 +697,8 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
private void unselectMessage() {
|
||||
commitFragmentTransaction(uninstallMessageViewFragment(
|
||||
mActivity.getFragmentManager().beginTransaction()));
|
||||
if (mMessageListFragment != null) {
|
||||
mMessageListFragment.setSelectedMessage(Message.NO_MESSAGE);
|
||||
if (isMessageListInstalled()) {
|
||||
getMessageListFragment().setSelectedMessage(Message.NO_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -891,7 +802,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
public boolean onBackPressed(boolean isSystemBackKey) {
|
||||
if (mThreePane.onBackPressed(isSystemBackKey)) {
|
||||
return true;
|
||||
} else if (isMailboxListInstalled() && mMailboxListFragment.navigateUp()) {
|
||||
} else if (isMailboxListInstalled() && getMailboxListFragment().navigateUp()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1061,7 +972,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
final int visiblePanes = mThreePane.getVisiblePanes();
|
||||
final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
|
||||
return leftPaneHidden
|
||||
|| (isMailboxListInstalled() && !mMailboxListFragment.isRoot());
|
||||
|| (isMailboxListInstalled() && !getMailboxListFragment().isRoot());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package com.android.email.activity;
|
|||
import com.android.email.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
|
@ -123,4 +124,16 @@ public class UiUtilities {
|
|||
public static void setVisibilitySafe(View parent, int viewId, int visibility) {
|
||||
setVisibilitySafe(parent.findViewById(viewId), visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by an {@link Fragment} to install itself to the host activity.
|
||||
*
|
||||
* @see FragmentInstallable
|
||||
*/
|
||||
public static void installFragment(Fragment fragment) {
|
||||
final Activity a = fragment.getActivity();
|
||||
if (a instanceof FragmentInstallable) {
|
||||
((FragmentInstallable) a).onInstallFragment(fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue