Refactoring MessageListXL
I always thought our Activities are way too fat, meaning we've put too many things into activities without any structure. The major problems with this are: - They have too many fields, which are not final and not even orthogonal. This makes them very hard to understand/maintain. Changing one tiny bit can always cause unanticipated side-effects. - Very hard, or almost impossible to test. I really think we should break them into independent and self-contained subcomponents which can be tested separately. Introducing MessageListXLStateManager, which manages the current account, mailbox and message, and show/hide/update fragments accordingly for MessageListXL. With this class, MessageListXL will be able to switch accounts/mailboxes/ messages by just calling the methods such as selectAccount(), without worrying about when to show/hide what fragment and how to initialize them. (In other words, MessageListXLStateManager encapsulates the two-pane screen transition. It's not intended to be reused for the phone UI.) I didn't make it a nested class in MessageListXL, because nested classes can't have real private members (private member are accessible from outer classes and even brother classes!!), and I wanted it to be really self-contained anyway. Change-Id: I1c121e99e30f12cc118e1c35abc9b30f49939a4a
This commit is contained in:
parent
f08b061ea8
commit
02fa70aa18
|
@ -51,7 +51,12 @@ public class Email extends Application {
|
|||
public static boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* If this is enabled than logging that normally hides sensitive information
|
||||
* If true, logging regarding activity/fragment lifecycle will be enabled.
|
||||
*/
|
||||
public static final boolean DEBUG_LIFECYCLE = true; // STOPSHIP Turn this off.
|
||||
|
||||
/**
|
||||
* If this is enabled then logging that normally hides sensitive information
|
||||
* like passwords will show that information.
|
||||
*/
|
||||
public static final boolean DEBUG_SENSITIVE = false;
|
||||
|
|
|
@ -97,7 +97,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onCreate");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onCreate");
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mActivity = getActivity();
|
||||
|
@ -106,7 +108,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onActivityCreated");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onActivityCreated");
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
ListView listView = getListView();
|
||||
|
@ -123,7 +127,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
* @param accountId the account we're looking at
|
||||
*/
|
||||
public void openMailboxes(long accountId) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment openMailboxes");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment openMailboxes");
|
||||
}
|
||||
if (accountId == -1) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
|
@ -141,7 +147,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onStart");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onStart");
|
||||
}
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mAccountId != -1) {
|
||||
|
@ -154,7 +162,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onResume");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onResume");
|
||||
}
|
||||
mStarted = false;
|
||||
super.onResume();
|
||||
updateMessageCount();
|
||||
|
@ -165,7 +175,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onStop");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onStop");
|
||||
}
|
||||
super.onStop();
|
||||
cancelAllTasks();
|
||||
}
|
||||
|
@ -175,7 +187,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onDestroy");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onDestroy");
|
||||
}
|
||||
super.onDestroy();
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
|
@ -183,7 +197,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MailboxListFragment onSaveInstanceState");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MailboxListFragment onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onCreate");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onCreate");
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
mActivity = getActivity();
|
||||
mResolver = mActivity.getContentResolver();
|
||||
|
@ -146,7 +148,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onActivityCreated");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onActivityCreated");
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
ListView listView = getListView();
|
||||
|
@ -169,7 +173,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onStart");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onStart");
|
||||
}
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mMailboxId != -1) {
|
||||
|
@ -179,14 +185,18 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onStop");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onStop");
|
||||
}
|
||||
mStarted = false;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onResume");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onResume");
|
||||
}
|
||||
super.onResume();
|
||||
restoreListPosition();
|
||||
autoRefreshStaleMailbox();
|
||||
|
@ -194,7 +204,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onDestroy");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onDestroy");
|
||||
}
|
||||
Utility.cancelTaskInterrupt(mLoadMessagesTask);
|
||||
mLoadMessagesTask = null;
|
||||
Utility.cancelTaskInterrupt(mSetFooterTask);
|
||||
|
@ -208,7 +220,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment onSaveInstanceState");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
saveListPosition();
|
||||
outState.putInt(STATE_SELECTED_POSITION, mSavedItemPosition);
|
||||
|
@ -249,7 +263,9 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
* {@link Mailbox#QUERY_ALL_INBOXES}. -1 is not allowed.
|
||||
*/
|
||||
public void openMailbox(long accountId, long mailboxId) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListFragment openMailbox");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListFragment openMailbox");
|
||||
}
|
||||
if (mailboxId == -1) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.android.email.R;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.content.Context;
|
||||
import android.content.Loader;
|
||||
|
@ -31,179 +30,182 @@ import android.util.Log;
|
|||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// TODO Where/when/how do we close loaders?? Do we have to? Getting this error:
|
||||
// Finalizing a Cursor that has not been deactivated or closed.
|
||||
// database = /data/data/com.google.android.email/databases/EmailProvider.db,
|
||||
// table = Account, query = SELECT _id, displayName, emailAddress FROM Account
|
||||
|
||||
/**
|
||||
* Two pane activity for XL screen devices.
|
||||
*
|
||||
* TOOD Test it!
|
||||
* The main (two-pane) activity for XL devices.
|
||||
*/
|
||||
public class MessageListXL extends Activity implements View.OnClickListener {
|
||||
private static final String BUNDLE_KEY_ACCOUNT_ID = "MessageListXl.account_id";
|
||||
private static final String BUNDLE_KEY_MAILBOX_ID = "MessageListXl.mailbox_id";
|
||||
private static final String BUNDLE_KEY_MESSAGE_ID = "MessageListXl.message_id";
|
||||
|
||||
public class MessageListXL extends Activity implements View.OnClickListener,
|
||||
MessageListXLFragmentManager.TargetActivity {
|
||||
private static final int LOADER_ID_DEFAULT_ACCOUNT = 0;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private long mAccountId = -1;
|
||||
private long mMailboxId = -1;
|
||||
private long mMessageId = -1;
|
||||
private View mMessageViewButtonPanel;
|
||||
private View mMoveToNewerButton;
|
||||
private View mMoveToOlderButton;
|
||||
|
||||
private MailboxListFragment mMailboxListFragment;
|
||||
private MessageListFragment mMessageListFragment;
|
||||
private MessageViewFragment mMessageViewFragment;
|
||||
|
||||
private View mMessageViewButtons;
|
||||
private View mMoveToNewer;
|
||||
private View mMoveToOlder;
|
||||
|
||||
private boolean mActivityInitialized;
|
||||
private final ArrayList<Fragment> mRestoredFragments = new ArrayList<Fragment>();
|
||||
private MessageOrderManager mOrderManager;
|
||||
|
||||
private final MessageListXLFragmentManager mFragmentManager
|
||||
= new MessageListXLFragmentManager(this);
|
||||
|
||||
private final MessageOrderManagerCallback mMessageOrderManagerCallback
|
||||
= new MessageOrderManagerCallback();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.message_list_xl);
|
||||
|
||||
final boolean isRestoring = (savedInstanceState != null);
|
||||
|
||||
mContext = getApplicationContext();
|
||||
|
||||
mMessageViewButtons = findViewById(R.id.message_view_buttons);
|
||||
mMoveToNewer = findViewById(R.id.moveToNewer);
|
||||
mMoveToOlder = findViewById(R.id.moveToOlder);
|
||||
mMoveToNewer.setOnClickListener(this);
|
||||
mMoveToOlder.setOnClickListener(this);
|
||||
mFragmentManager.setMailboxListFragmentCallback(new MailboxListFragmentCallback());
|
||||
mFragmentManager.setMessageListFragmentCallback(new MessageListFragmentCallback());
|
||||
mFragmentManager.setMessageViewFragmentCallback(new MessageViewFragmentCallback());
|
||||
|
||||
mMessageViewButtonPanel = findViewById(R.id.message_view_buttons);
|
||||
mMoveToNewerButton = findViewById(R.id.moveToNewer);
|
||||
mMoveToOlderButton = findViewById(R.id.moveToOlder);
|
||||
mMoveToNewerButton.setOnClickListener(this);
|
||||
mMoveToOlderButton.setOnClickListener(this);
|
||||
|
||||
if (isRestoring) {
|
||||
restoreSavedState(savedInstanceState);
|
||||
mFragmentManager.loadState(savedInstanceState);
|
||||
}
|
||||
if (mAccountId == -1) {
|
||||
if (!mFragmentManager.isAccountSelected()) {
|
||||
loadDefaultAccount();
|
||||
}
|
||||
// TODO Initialize accounts dropdown.
|
||||
|
||||
mActivityInitialized = true;
|
||||
if (isRestoring) {
|
||||
initRestoredFragments();
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreSavedState(Bundle savedInstanceState) {
|
||||
mAccountId = savedInstanceState.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
|
||||
mMailboxId = savedInstanceState.getLong(BUNDLE_KEY_MAILBOX_ID, -1);
|
||||
mMessageId = savedInstanceState.getLong(BUNDLE_KEY_MESSAGE_ID, -1);
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXl: Restoring "
|
||||
+ mAccountId + "," + mMailboxId + "," + mMessageId);
|
||||
}
|
||||
// TODO load account list and show account selector
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXL onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong(BUNDLE_KEY_ACCOUNT_ID, mAccountId);
|
||||
outState.putLong(BUNDLE_KEY_MAILBOX_ID, mMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_MESSAGE_ID, mMessageId);
|
||||
mFragmentManager.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onStart");
|
||||
super.onStart();
|
||||
startMessageOrderManager();
|
||||
|
||||
mFragmentManager.setStart();
|
||||
|
||||
if (mFragmentManager.isMessageSelected()) {
|
||||
updateMessageOrderManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onResume");
|
||||
super.onResume();
|
||||
|
||||
// TODO Add stuff that's done in MessageList.onResume().
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onPause");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onStop");
|
||||
super.onStop();
|
||||
|
||||
mFragmentManager.onStop();
|
||||
|
||||
stopMessageOrderManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Email.LOG_TAG, "MessageListXL onDestroy");
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment fragment) {
|
||||
if (!mActivityInitialized) {
|
||||
// Fragments are being restored in super.onCreate().
|
||||
// We can't initialize fragments until the activity is initialized, so remember them for
|
||||
// now, and initialize them later in initRestoredFragments().
|
||||
mRestoredFragments.add(fragment);
|
||||
return;
|
||||
}
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXl.onAttachFragment fragment=" + fragment.getClass());
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXL onAttachFragment " + fragment.getClass());
|
||||
}
|
||||
super.onAttachFragment(fragment);
|
||||
initFragment(fragment);
|
||||
mFragmentManager.onAttachFragment(fragment);
|
||||
}
|
||||
|
||||
private void initFragment(Fragment fragment) {
|
||||
if (fragment instanceof MailboxListFragment) {
|
||||
initMailboxListFragment((MailboxListFragment) fragment);
|
||||
} else if (fragment instanceof MessageListFragment) {
|
||||
initMessageListFragment((MessageListFragment) fragment);
|
||||
} else if (fragment instanceof MessageViewFragment) {
|
||||
initMessageViewFragment((MessageViewFragment) fragment);
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXL onBackPressed");
|
||||
}
|
||||
if (mFragmentManager.isMessageSelected()) {
|
||||
// Go back to the message list.
|
||||
// TODO: This works for now, but it doesn't restore the list view state, e.g. scroll
|
||||
// position.
|
||||
// TODO: FragmentTransaction *does* support backstack, but the behavior isn't too clear
|
||||
// at this point.
|
||||
mFragmentManager.selectMailbox(mFragmentManager.getMailboxId());
|
||||
} else {
|
||||
// Perform the default behavior == close the activity.
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.moveToOlder:
|
||||
moveToOlder();
|
||||
break;
|
||||
case R.id.moveToNewer:
|
||||
moveToNewer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link #onCreate}.
|
||||
* Initializes the fragmetns that are restored in super.onCreate().
|
||||
* Start {@link MessageOrderManager} if not started, and sync it to the current message.
|
||||
*/
|
||||
private void initRestoredFragments() {
|
||||
for (Fragment f : mRestoredFragments) {
|
||||
initFragment(f);
|
||||
}
|
||||
mRestoredFragments.clear();
|
||||
}
|
||||
|
||||
private void startMessageOrderManager() {
|
||||
if (mMailboxId == -1) {
|
||||
private void updateMessageOrderManager() {
|
||||
if (!mFragmentManager.isMailboxSelected()) {
|
||||
return;
|
||||
}
|
||||
if (mOrderManager != null && mOrderManager.getMailboxId() == mMailboxId) {
|
||||
return;
|
||||
final long mailboxId = mFragmentManager.getMailboxId();
|
||||
if (mOrderManager == null || mOrderManager.getMailboxId() != mailboxId) {
|
||||
stopMessageOrderManager();
|
||||
mOrderManager = new MessageOrderManager(this, mailboxId, mMessageOrderManagerCallback);
|
||||
}
|
||||
if (mFragmentManager.isMessageSelected()) {
|
||||
mOrderManager.moveTo(mFragmentManager.getMessageId());
|
||||
}
|
||||
stopMessageOrderManager();
|
||||
mOrderManager = new MessageOrderManager(this, mMailboxId,
|
||||
new MessageOrderManager.Callback() {
|
||||
@Override
|
||||
public void onMessagesChanged() {
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotFound() {
|
||||
// Current message removed.
|
||||
selectMailbox(mMailboxId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class MessageOrderManagerCallback implements MessageOrderManager.Callback {
|
||||
@Override
|
||||
public void onMessagesChanged() {
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotFound() {
|
||||
// TODO Current message gone
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop {@link MessageOrderManager}.
|
||||
*/
|
||||
private void stopMessageOrderManager() {
|
||||
if (mOrderManager != null) {
|
||||
mOrderManager.close();
|
||||
|
@ -226,12 +228,15 @@ public class MessageListXL extends Activity implements View.OnClickListener {
|
|||
if (accountId == null || accountId == -1) {
|
||||
onNoAccountFound();
|
||||
} else {
|
||||
selectAccount(accountId);
|
||||
mFragmentManager.selectAccount(accountId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the default account is not found, i.e. there's no account set up.
|
||||
*/
|
||||
private void onNoAccountFound() {
|
||||
// Open Welcome, which in turn shows the adding a new account screen.
|
||||
Welcome.actionStart(this);
|
||||
|
@ -239,234 +244,126 @@ public class MessageListXL extends Activity implements View.OnClickListener {
|
|||
return;
|
||||
}
|
||||
|
||||
// NOTE These selectXxx are *not* only methods where mXxxId's are changed.
|
||||
// When the activity is re-created (e.g. for orientation change), the following things happen.
|
||||
// - mXxxId's are restored from Bundle
|
||||
// - Fragments are restored by the framework (in super.onCreate())
|
||||
// - mXxxId's are set to fragments in initXxxFragment()
|
||||
//
|
||||
// So, if you want to do something when, for example, the current account changes,
|
||||
// selectAccount() is probably not a good place to do it, because it'll be skipped when
|
||||
// the activity is re-created.
|
||||
// Instead, do that in initXxxFragment(). Alternatively, adding the same procedure to
|
||||
// initRestoredFragments() too will probably work.
|
||||
|
||||
private void selectAccount(long accountId) {
|
||||
// TODO Handle "combined mailboxes". Who should take care of it? This activity?
|
||||
// MailboxListFragment??
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectAccount mAccountId=" + mAccountId);
|
||||
}
|
||||
if (accountId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (mAccountId == accountId) {
|
||||
return;
|
||||
}
|
||||
mAccountId = accountId;
|
||||
mMailboxId = -1;
|
||||
mMessageId = -1;
|
||||
|
||||
// TODO We don't have to replace the fragment, Just update it.
|
||||
// That will be in accordance with our back model.
|
||||
|
||||
final MailboxListFragment fragment = new MailboxListFragment();
|
||||
final FragmentTransaction ft = openFragmentTransaction();
|
||||
ft.replace(R.id.left_pane, fragment);
|
||||
if (mMessageListFragment != null) {
|
||||
ft.remove(mMessageListFragment);
|
||||
}
|
||||
if (mMessageViewFragment != null) {
|
||||
ft.remove(mMessageListFragment);
|
||||
}
|
||||
ft.commit();
|
||||
|
||||
// TODO Open inbox for the selected account.
|
||||
}
|
||||
|
||||
private void selectMailbox(long mailboxId) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMailbox mMailboxId=" + mMailboxId);
|
||||
}
|
||||
if (mMailboxId == mailboxId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO We don't have to replace the fragment, if it's already the message list. Just
|
||||
// update it.
|
||||
// That will be in accordance with our back model.
|
||||
|
||||
mMailboxId = mailboxId;
|
||||
mMessageId = -1;
|
||||
MessageListFragment fragment = new MessageListFragment();
|
||||
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
|
||||
}
|
||||
|
||||
private void selectMessage(long messageId) {
|
||||
// TODO: Deal with draft messages. (open MessageCompose instead)
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMessage messageId=" + mMessageId);
|
||||
}
|
||||
if (mMessageId == messageId) {
|
||||
return;
|
||||
}
|
||||
mMessageId = messageId;
|
||||
MessageViewFragment fragment = new MessageViewFragment();
|
||||
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
|
||||
}
|
||||
|
||||
private void initMailboxListFragment(MailboxListFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMailboxListFragment mAccountId=" + mAccountId);
|
||||
}
|
||||
if (mAccountId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageListFragment = null;
|
||||
mMessageViewFragment = null;
|
||||
mMailboxListFragment = fragment;
|
||||
fragment.setCallback(new MailboxListFragment.Callback() {
|
||||
@Override
|
||||
public void onRefresh(long accountId, long mailboxId) {
|
||||
// Will be removed.
|
||||
}
|
||||
|
||||
// TODO Rename to onSelectMailbox
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId) {
|
||||
selectMailbox(mailboxId);
|
||||
}
|
||||
});
|
||||
fragment.openMailboxes(mAccountId);
|
||||
}
|
||||
|
||||
private void initMessageListFragment(MessageListFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMessageListFragment mMailboxId=" + mMailboxId);
|
||||
}
|
||||
if (mAccountId == -1 || mMailboxId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageListFragment = fragment;
|
||||
mMessageViewFragment = null;
|
||||
mMessageViewButtons.setVisibility(View.GONE);
|
||||
fragment.setCallback(new MessageListFragment.Callback() {
|
||||
@Override
|
||||
public void onSelectionChanged() {
|
||||
// TODO Context mode
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO Rename to onSelectMessage
|
||||
public void onMessageOpen(long messageId, long mailboxId) { // RENAME: OpenMessage ?
|
||||
selectMessage(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxNotFound() { // RENAME: NotExists? (see MessageViewFragment)
|
||||
// TODO: What to do??
|
||||
}
|
||||
});
|
||||
fragment.openMailbox(mAccountId, mMailboxId);
|
||||
}
|
||||
|
||||
private void initMessageViewFragment(MessageViewFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMessageViewFragment messageId=" + mMessageId);
|
||||
}
|
||||
if (mMessageId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageViewFragment = fragment;
|
||||
mMessageListFragment = null;
|
||||
mMessageViewButtons.setVisibility(View.VISIBLE);
|
||||
fragment.setCallback(new MessageViewFragment.Callback() {
|
||||
@Override
|
||||
public boolean onUrlInMessageClicked(String url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRespondedToInvite(int response) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSetUnread() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotExists() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageStarted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentStarted(String attachmentName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalendarLinkClicked(long epochEventStartTime) {
|
||||
}
|
||||
});
|
||||
fragment.openMessage(mMessageId);
|
||||
startMessageOrderManager();
|
||||
mOrderManager.moveTo(mMessageId);
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable/enable the previous/next buttons for the message view.
|
||||
*/
|
||||
private void updateNavigationArrows() {
|
||||
mMoveToNewer.setEnabled((mOrderManager != null) && mOrderManager.canMoveToNewer());
|
||||
mMoveToOlder.setEnabled((mOrderManager != null) && mOrderManager.canMoveToOlder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.moveToOlder:
|
||||
moveToOlder();
|
||||
break;
|
||||
case R.id.moveToNewer:
|
||||
moveToNewer();
|
||||
break;
|
||||
}
|
||||
mMoveToNewerButton.setEnabled((mOrderManager != null) && mOrderManager.canMoveToNewer());
|
||||
mMoveToOlderButton.setEnabled((mOrderManager != null) && mOrderManager.canMoveToOlder());
|
||||
}
|
||||
|
||||
private boolean moveToOlder() {
|
||||
if (mOrderManager != null && mOrderManager.moveToOlder()) {
|
||||
mMessageId = mOrderManager.getCurrentMessageId();
|
||||
mMessageViewFragment.openMessage(mMessageId);
|
||||
if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
|
||||
&& mOrderManager.moveToOlder()) {
|
||||
mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean moveToNewer() {
|
||||
if (mOrderManager != null && mOrderManager.moveToNewer()) {
|
||||
mMessageId = mOrderManager.getCurrentMessageId();
|
||||
mMessageViewFragment.openMessage(mMessageId);
|
||||
if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
|
||||
&& mOrderManager.moveToNewer()) {
|
||||
mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class MailboxListFragmentCallback implements MailboxListFragment.Callback {
|
||||
@Override
|
||||
public void onRefresh(long accountId, long mailboxId) {
|
||||
// Will be removed.
|
||||
}
|
||||
|
||||
// TODO Rename to onSelectMailbox
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId) {
|
||||
mFragmentManager.selectMailbox(mailboxId);
|
||||
}
|
||||
}
|
||||
|
||||
private class MessageListFragmentCallback implements MessageListFragment.Callback {
|
||||
@Override
|
||||
public void onSelectionChanged() {
|
||||
// TODO Context mode
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO Rename to onSelectMessage
|
||||
public void onMessageOpen(long messageId, long mailboxId) { // RENAME: OpenMessage ?
|
||||
// TODO Deal with drafts. (Open MessageCompose instead.)
|
||||
mFragmentManager.selectMessage(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxNotFound() { // RENAME: NotExists? (see MessageViewFragment)
|
||||
// TODO: What to do??
|
||||
}
|
||||
}
|
||||
|
||||
private class MessageViewFragmentCallback implements MessageViewFragment.Callback {
|
||||
@Override
|
||||
public boolean onUrlInMessageClicked(String url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRespondedToInvite(int response) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSetUnread() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotExists() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageStarted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentStarted(String attachmentName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalendarLinkClicked(long epochEventStartTime) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageViewFragmentShown(long accountId, long mailboxId, long messageId) {
|
||||
mMessageViewButtonPanel.setVisibility(View.VISIBLE);
|
||||
|
||||
updateMessageOrderManager();
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageViewFragmentHidden() {
|
||||
mMessageViewButtonPanel.setVisibility(View.GONE);
|
||||
|
||||
stopMessageOrderManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* STOPSHIP: Remove this.
|
||||
* Rotate screen when the R key is pressed. Workaround for auto-orientation not working.
|
||||
|
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
TODO: When opening a mailbox I see this:
|
||||
D Email : com.android.email.activity.MailboxListFragment openMailboxes
|
||||
D Email : com.android.email.activity.MailboxListFragment onCreate *1 <- Why second instance???
|
||||
D Email : com.android.email.activity.MailboxListFragment onActivityCreated
|
||||
D Email : com.android.email.activity.MailboxListFragment onStart
|
||||
D Email : com.android.email.activity.MailboxListFragment onResume
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class manages what are showing on {@link MessageListXL} (i.e. account id, mailbox id, and
|
||||
* message id), and show/hide fragments accordingly.
|
||||
*
|
||||
* TODO: Test it. It's testable if we implement MockFragmentTransaction, which may be too early
|
||||
* to do so at this point. (API may not be stable enough yet.)
|
||||
*
|
||||
* TODO: See if the "restored fragments" hack can be removed if the fragments restore their
|
||||
* state by themselves. (That'll require phone activity changes as well.)
|
||||
*/
|
||||
class MessageListXLFragmentManager {
|
||||
private static final String BUNDLE_KEY_ACCOUNT_ID = "MessageListXl.state.account_id";
|
||||
private static final String BUNDLE_KEY_MAILBOX_ID = "MessageListXl.state.mailbox_id";
|
||||
private static final String BUNDLE_KEY_MESSAGE_ID = "MessageListXl.state.message_id";
|
||||
|
||||
/**
|
||||
* List of fragments that are restored by the framework when the activity is being re-created.
|
||||
* (e.g. for orientation change)
|
||||
*/
|
||||
private final ArrayList<Fragment> mRestoredFragments = new ArrayList<Fragment>();
|
||||
|
||||
private boolean mIsActivityStarted;
|
||||
|
||||
/** Current account id. (-1 = not selected) */
|
||||
private long mAccountId = -1;
|
||||
|
||||
/** Current mailbox id. (-1 = not selected) */
|
||||
private long mMailboxId = -1;
|
||||
|
||||
/** Current message id. (-1 = not selected) */
|
||||
private long mMessageId = -1;
|
||||
|
||||
private MailboxListFragment mMailboxListFragment;
|
||||
private MessageListFragment mMessageListFragment;
|
||||
private MessageViewFragment mMessageViewFragment;
|
||||
|
||||
private MailboxListFragment.Callback mMailboxListFragmentCallback;
|
||||
private MessageListFragment.Callback mMessageListFragmentCallback;
|
||||
private MessageViewFragment.Callback mMessageViewFragmentCallback;
|
||||
|
||||
/**
|
||||
* The interface that {@link MessageListXL} implements. We don't call its methods directly,
|
||||
* in the hope that it'll make writing tests easier.
|
||||
*/
|
||||
public interface TargetActivity {
|
||||
public FragmentTransaction openFragmentTransaction();
|
||||
/**
|
||||
* Called when MessageViewFragment is being shown.
|
||||
* {@link MessageListXL} uses it to show the navigation buttons.
|
||||
*/
|
||||
public void onMessageViewFragmentShown(long accountId, long mailboxId, long messageId);
|
||||
/**
|
||||
* Called when MessageViewFragment is being hidden.
|
||||
* {@link MessageListXL} uses it to hide the navigation buttons.
|
||||
*/
|
||||
public void onMessageViewFragmentHidden();
|
||||
}
|
||||
|
||||
private final TargetActivity mTargetActivity;
|
||||
|
||||
public MessageListXLFragmentManager(TargetActivity targetActivity) {
|
||||
mTargetActivity = targetActivity;
|
||||
}
|
||||
|
||||
/** Set callback for fragment. */
|
||||
public void setMailboxListFragmentCallback(
|
||||
MailboxListFragment.Callback mailboxListFragmentCallback) {
|
||||
mMailboxListFragmentCallback = mailboxListFragmentCallback;
|
||||
}
|
||||
|
||||
/** Set callback for fragment. */
|
||||
public void setMessageListFragmentCallback(
|
||||
MessageListFragment.Callback messageListFragmentCallback) {
|
||||
mMessageListFragmentCallback = messageListFragmentCallback;
|
||||
}
|
||||
|
||||
/** Set callback for fragment. */
|
||||
public void setMessageViewFragmentCallback(
|
||||
MessageViewFragment.Callback messageViewFragmentCallback) {
|
||||
mMessageViewFragmentCallback = messageViewFragmentCallback;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return mAccountId;
|
||||
}
|
||||
|
||||
public long getMailboxId() {
|
||||
return mMailboxId;
|
||||
}
|
||||
|
||||
public long getMessageId() {
|
||||
return mMessageId;
|
||||
}
|
||||
|
||||
public boolean isAccountSelected() {
|
||||
return getAccountId() != -1;
|
||||
}
|
||||
|
||||
public boolean isMailboxSelected() {
|
||||
return getMailboxId() != -1;
|
||||
}
|
||||
|
||||
public boolean isMessageSelected() {
|
||||
return getMessageId() != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link MessageListXL#onStart()}.
|
||||
*
|
||||
* When the activity is being started, we initialize the "restored" fragments.
|
||||
*
|
||||
* @see #initRestoredFragments
|
||||
*/
|
||||
public void setStart() {
|
||||
if (mIsActivityStarted) {
|
||||
return;
|
||||
}
|
||||
mIsActivityStarted = true;
|
||||
initRestoredFragments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link MessageListXL#onStop()}.
|
||||
*/
|
||||
public void onStop() {
|
||||
if (!mIsActivityStarted) {
|
||||
return;
|
||||
}
|
||||
mIsActivityStarted = false;
|
||||
}
|
||||
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putLong(BUNDLE_KEY_ACCOUNT_ID, mAccountId);
|
||||
outState.putLong(BUNDLE_KEY_MAILBOX_ID, mMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_MESSAGE_ID, mMessageId);
|
||||
}
|
||||
|
||||
public void loadState(Bundle savedInstanceState) {
|
||||
mAccountId = savedInstanceState.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
|
||||
mMailboxId = savedInstanceState.getLong(BUNDLE_KEY_MAILBOX_ID, -1);
|
||||
mMessageId = savedInstanceState.getLong(BUNDLE_KEY_MESSAGE_ID, -1);
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXLFragmentManager: Restoring "
|
||||
+ mAccountId + "," + mMailboxId + "," + mMessageId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link MessageListXL#onAttachFragment}.
|
||||
*
|
||||
* If the activity is not started yet, just store it in {@link #mRestoredFragments} to
|
||||
* initialize it later.
|
||||
*/
|
||||
public void onAttachFragment(Fragment fragment) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXLFragmentManager.onAttachFragment fragment=" +
|
||||
fragment.getClass());
|
||||
}
|
||||
if (!mIsActivityStarted) {
|
||||
mRestoredFragments.add(fragment);
|
||||
return;
|
||||
}
|
||||
if (fragment instanceof MailboxListFragment) {
|
||||
updateMailboxListFragment((MailboxListFragment) fragment);
|
||||
} else if (fragment instanceof MessageListFragment) {
|
||||
updateMessageListFragment((MessageListFragment) fragment);
|
||||
} else if (fragment instanceof MessageViewFragment) {
|
||||
updateMessageViewFragment((MessageViewFragment) fragment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link #setActivityStarted} to initialize the "restored" fragments.
|
||||
*/
|
||||
private void initRestoredFragments() {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXLFragmentManager.initRestoredFragments");
|
||||
}
|
||||
for (Fragment f : mRestoredFragments) {
|
||||
onAttachFragment(f);
|
||||
}
|
||||
mRestoredFragments.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call it to select an account.
|
||||
*/
|
||||
public void selectAccount(long accountId) {
|
||||
// TODO Handle "combined mailboxes".
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectAccount mAccountId=" + accountId);
|
||||
}
|
||||
if (accountId == -1) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
if (mAccountId == accountId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update members.
|
||||
mAccountId = accountId;
|
||||
mMailboxId = -1;
|
||||
mMessageId = -1;
|
||||
|
||||
// Replace fragments if necessary.
|
||||
final FragmentTransaction ft = mTargetActivity.openFragmentTransaction();
|
||||
if (mMailboxListFragment == null) {
|
||||
// The left pane not set yet.
|
||||
|
||||
// We can put it directly in the layout file, but then it'll have slightly different
|
||||
// lifecycle as the other fragments. Let's create it here this way for now.
|
||||
MailboxListFragment f = new MailboxListFragment();
|
||||
ft.replace(R.id.left_pane, f);
|
||||
}
|
||||
if (mMessageListFragment != null) {
|
||||
ft.remove(mMessageListFragment);
|
||||
mMessageListFragment = null;
|
||||
}
|
||||
if (mMessageViewFragment != null) {
|
||||
ft.remove(mMessageViewFragment);
|
||||
mMessageViewFragment = null;
|
||||
mTargetActivity.onMessageViewFragmentHidden(); // Don't forget to tell the activity.
|
||||
}
|
||||
ft.commit();
|
||||
|
||||
// If it's already shown, update it.
|
||||
if (mMailboxListFragment != null) {
|
||||
updateMailboxListFragment(mMailboxListFragment);
|
||||
} else {
|
||||
Log.w(Email.LOG_TAG, "MailboxListFragment not set yet.");
|
||||
}
|
||||
|
||||
// TODO Open the inbox on the right pane.
|
||||
}
|
||||
|
||||
private void updateMailboxListFragment(MailboxListFragment fragment) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "updateMailboxListFragment mAccountId=" + mAccountId);
|
||||
}
|
||||
if (mAccountId == -1) { // Shouldn't happen
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMailboxListFragment = fragment;
|
||||
fragment.setCallback(mMailboxListFragmentCallback);
|
||||
fragment.openMailboxes(mAccountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call it to select a mailbox.
|
||||
*
|
||||
* We assume the mailbox selected here belongs to the account selected with
|
||||
* {@link #selectAccount}.
|
||||
*/
|
||||
public void selectMailbox(long mailboxId) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMailbox mMailboxId=" + mailboxId);
|
||||
}
|
||||
if (mailboxId == -1) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
if ((mMailboxId == mailboxId) && !isMessageSelected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update members.
|
||||
mMailboxId = mailboxId;
|
||||
mMessageId = -1;
|
||||
|
||||
// Update fragments.
|
||||
if (mMessageListFragment == null) {
|
||||
MessageListFragment f = new MessageListFragment();
|
||||
mTargetActivity.openFragmentTransaction().replace(R.id.right_pane, f).commit();
|
||||
|
||||
if (mMessageViewFragment != null) {
|
||||
// Message view will disappear.
|
||||
mMessageViewFragment = null;
|
||||
mTargetActivity.onMessageViewFragmentHidden(); // Don't forget to tell the activity.
|
||||
}
|
||||
} else {
|
||||
updateMessageListFragment(mMessageListFragment);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMessageListFragment(MessageListFragment fragment) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "updateMessageListFragment mMailboxId=" + mMailboxId);
|
||||
}
|
||||
if (mAccountId == -1 || mMailboxId == -1) { // Shouldn't happen
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageListFragment = fragment;
|
||||
|
||||
fragment.setCallback(mMessageListFragmentCallback);
|
||||
fragment.openMailbox(mAccountId, mMailboxId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call it to select a mailbox.
|
||||
*
|
||||
* We assume the message passed here belongs to the account/mailbox selected with
|
||||
* {@link #selectAccount} and {@link #selectMailbox}.
|
||||
*/
|
||||
public void selectMessage(long messageId) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMessage messageId=" + messageId);
|
||||
}
|
||||
if (messageId == -1) {
|
||||
throw new InvalidParameterException();
|
||||
}
|
||||
if (mMessageId == messageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update member.
|
||||
mMessageId = messageId;
|
||||
|
||||
// Update fragments.
|
||||
if (mMessageViewFragment == null) {
|
||||
MessageViewFragment f = new MessageViewFragment();
|
||||
|
||||
// TODO We want to support message view -> [back] -> message list, but the back behavior
|
||||
// with addToBackStack() is not too clear. We do it manually for now.
|
||||
// See MessageListXL.onBackPressed().
|
||||
mTargetActivity.openFragmentTransaction().replace(R.id.right_pane, f)
|
||||
// .addToBackStack(null)
|
||||
.commit();
|
||||
mMessageListFragment = null;
|
||||
} else {
|
||||
updateMessageViewFragment(mMessageViewFragment);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMessageViewFragment(MessageViewFragment fragment) {
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "updateMessageViewFragment messageId=" + mMessageId);
|
||||
}
|
||||
if (mAccountId == -1 || mMailboxId == -1 || mMessageId == -1) { // Shouldn't happen
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageViewFragment = fragment;
|
||||
fragment.setCallback(mMessageViewFragmentCallback);
|
||||
fragment.openMessage(mMessageId);
|
||||
mTargetActivity.onMessageViewFragmentShown(getAccountId(), getMailboxId(), getMessageId());
|
||||
}
|
||||
}
|
|
@ -265,7 +265,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onCreate");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onCreate");
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mContext = getActivity().getApplicationContext();
|
||||
|
@ -287,7 +289,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onCreateView");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onCreateView");
|
||||
}
|
||||
final View view = inflater.inflate(R.layout.message_view_fragment, container, false);
|
||||
|
||||
mSubjectView = (TextView) view.findViewById(R.id.subject);
|
||||
|
@ -329,14 +333,18 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onActivityCreated");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onActivityCreated");
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mController.addResultCallback(mControllerCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onStart");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onStart");
|
||||
}
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mMessageId != -1 || mFileEmailUri != null) {
|
||||
|
@ -346,26 +354,34 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onResume");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onResume");
|
||||
}
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onPause");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onPause");
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onStop");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onStop");
|
||||
}
|
||||
mStarted = false;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onDestroy");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onDestroy");
|
||||
}
|
||||
mController.removeResultCallback(mControllerCallback);
|
||||
cancelAllTasks();
|
||||
mMessageContentView.destroy();
|
||||
|
@ -384,7 +400,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment onSaveInstanceState");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
@ -421,7 +439,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
/** Called by activities to set an id of a message to open. */
|
||||
public void openMessage(long messageId) {
|
||||
if (Email.DEBUG) Log.d(Email.LOG_TAG, "MessageViewFragment openMessage");
|
||||
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageViewFragment openMessage");
|
||||
}
|
||||
mFileEmailUri = null;
|
||||
mMessageId = messageId;
|
||||
mAccountId = -1;
|
||||
|
|
Loading…
Reference in New Issue