ActionBarController.java revision ad71b358c639b3dc24b5047338af6f6b6b211f65
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email.activity; 18 19import com.android.email.R; 20import com.android.emailcommon.Logging; 21import com.android.emailcommon.provider.EmailContent.Account; 22 23import android.app.ActionBar; 24import android.app.LoaderManager; 25import android.app.LoaderManager.LoaderCallbacks; 26import android.content.Context; 27import android.content.Loader; 28import android.database.Cursor; 29import android.os.Bundle; 30import android.view.LayoutInflater; 31import android.view.View; 32import android.widget.TextView; 33 34/** 35 * Manages the account name and the custom view part on the action bar. 36 */ 37public class ActionBarController { 38 private static final int LOADER_ID_ACCOUNT_LIST 39 = EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 0; 40 41 private final Context mContext; 42 private final LoaderManager mLoaderManager; 43 private final ActionBar mActionBar; 44 45 private final View mActionBarMailboxNameView; 46 private final TextView mActionBarMailboxName; 47 private final TextView mActionBarUnreadCount; 48 49 private final ActionBarNavigationCallback mActionBarNavigationCallback = 50 new ActionBarNavigationCallback(); 51 52 private final AccountSelectorAdapter mAccountsSelectorAdapter; 53 private Cursor mAccountsSelectorCursor; 54 55 public final Callback mCallback; 56 57 public interface Callback { 58 /** @return true if an account is selected. */ 59 public boolean isAccountSelected(); 60 61 /** 62 * @return currently selected account ID, {@link Account#ACCOUNT_ID_COMBINED_VIEW}, 63 * or -1 if no account is selected. 64 */ 65 public long getUIAccountId(); 66 67 /** @return true if the current mailbox name should be shown. */ 68 public boolean shouldShowMailboxName(); 69 70 /** @return current mailbox name */ 71 public String getCurrentMailboxName(); 72 /** 73 * @return unread count for the current mailbox. (0 if the mailbox doesn't have the concept 74 * of "unread"; e.g. Drafts) 75 */ 76 public int getCurrentMailboxUnreadCount(); 77 78 /** @return the "UP" arrow should be shown. */ 79 public boolean shouldShowUp(); 80 81 /** 82 * Called when an account is selected on the account spinner. 83 * 84 * @param accountId ID of the selected account, or 85 * {@link Account#ACCOUNT_ID_COMBINED_VIEW}. 86 */ 87 public void onAccountSelected(long accountId); 88 89 /** Called when no accounts are found in the database. */ 90 public void onNoAccountsFound(); 91 } 92 93 public ActionBarController(Context context, LoaderManager loaderManager, 94 ActionBar actionBar, Callback callback) { 95 mContext = context; 96 mLoaderManager = loaderManager; 97 mActionBar = actionBar; 98 mCallback = callback; 99 mAccountsSelectorAdapter = new AccountSelectorAdapter(mContext); 100 101 mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME 102 | ActionBar.DISPLAY_SHOW_CUSTOM); 103 104 // The custom view for the current mailbox and the unread count. 105 final LayoutInflater inflater = LayoutInflater.from(mContext); 106 mActionBarMailboxNameView = inflater.inflate(R.layout.action_bar_current_mailbox, null); 107 final ActionBar.LayoutParams customViewLayout = new ActionBar.LayoutParams( 108 ActionBar.LayoutParams.WRAP_CONTENT, 109 ActionBar.LayoutParams.MATCH_PARENT); 110 customViewLayout.setMargins(mContext.getResources().getDimensionPixelSize( 111 R.dimen.action_bar_mailbox_name_left_margin) , 0, 0, 0); 112 mActionBar.setCustomView(mActionBarMailboxNameView, customViewLayout); 113 114 mActionBarMailboxName = UiUtilities.getView(mActionBarMailboxNameView, R.id.mailbox_name); 115 mActionBarUnreadCount = UiUtilities.getView(mActionBarMailboxNameView, R.id.unread_count); 116 } 117 118 /** 119 * Must be called when the host activity is created. 120 */ 121 public void onActivityCreated() { 122 loadAccounts(); 123 refresh(); 124 } 125 126 /** Used only in {@link #refresh()} to determine if the account has changed. */ 127 private long mLastAccountIdForDirtyCheck = -1; 128 129 /** 130 * Refresh the content. 131 */ 132 public void refresh() { 133 mActionBar.setDisplayOptions(mCallback.shouldShowUp() 134 ? ActionBar.DISPLAY_HOME_AS_UP : 0, ActionBar.DISPLAY_HOME_AS_UP); 135 136 mActionBarMailboxNameView.setVisibility(mCallback.shouldShowMailboxName() 137 ? View.VISIBLE : View.GONE); 138 139 mActionBarMailboxName.setText(mCallback.getCurrentMailboxName()); 140 141 // Note on action bar, we show only "unread count". Some mailboxes such as Outbox don't 142 // have the idea of "unread count", in which case we just omit the count. 143 mActionBarUnreadCount.setText(UiUtilities.getMessageCountForUi(mContext, 144 mCallback.getCurrentMailboxUnreadCount(), true)); 145 146 // Update the account list only when the account has changed. 147 if (mLastAccountIdForDirtyCheck != mCallback.getUIAccountId()) { 148 mLastAccountIdForDirtyCheck = mCallback.getUIAccountId(); 149 updateAccountList(); 150 } 151 } 152 153 /** 154 * Load account cursor, and update the action bar. 155 */ 156 private void loadAccounts() { 157 mLoaderManager.initLoader(LOADER_ID_ACCOUNT_LIST, null, 158 new LoaderCallbacks<Cursor>() { 159 @Override 160 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 161 return AccountSelectorAdapter.createLoader(mContext); 162 } 163 164 @Override 165 public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 166 mAccountsSelectorCursor = data; 167 updateAccountList(); 168 } 169 170 @Override 171 public void onLoaderReset(Loader<Cursor> loader) { 172 mAccountsSelectorCursor = null; 173 updateAccountList(); 174 } 175 }); 176 } 177 178 /** 179 * Called when the LOADER_ID_ACCOUNT_LIST loader loads the data. Update the account spinner 180 * on the action bar. 181 */ 182 private void updateAccountList() { 183 mAccountsSelectorAdapter.swapCursor(mAccountsSelectorCursor); 184 185 final ActionBar ab = mActionBar; 186 if (mAccountsSelectorCursor == null) { 187 // Cursor not ready or closed. 188 mAccountsSelectorAdapter.swapCursor(null); 189 ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 190 ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 191 return; 192 } 193 194 final int count = mAccountsSelectorCursor.getCount(); 195 if (count == 0) { 196 mCallback.onNoAccountsFound(); 197 return; 198 } 199 200 // If only one acount, don't show the dropdown. 201 if (count == 1) { 202 mAccountsSelectorCursor.moveToFirst(); 203 204 // Show the account name as the title. 205 ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); 206 ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 207 ab.setTitle(AccountSelectorAdapter.getAccountDisplayName(mAccountsSelectorCursor)); 208 return; 209 } 210 211 // Find the currently selected account, and select it. 212 int defaultSelection = 0; 213 if (mCallback.isAccountSelected()) { 214 final long accountId = mCallback.getUIAccountId(); 215 mAccountsSelectorCursor.moveToPosition(-1); 216 int i = 0; 217 while (mAccountsSelectorCursor.moveToNext()) { 218 if (accountId == AccountSelectorAdapter.getAccountId(mAccountsSelectorCursor)) { 219 defaultSelection = i; 220 break; 221 } 222 i++; 223 } 224 } 225 226 // Update the dropdown list. 227 if (ab.getNavigationMode() != ActionBar.NAVIGATION_MODE_LIST) { 228 ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 229 ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 230 ab.setListNavigationCallbacks(mAccountsSelectorAdapter, mActionBarNavigationCallback); 231 } 232 ab.setSelectedNavigationItem(defaultSelection); 233 } 234 235 private class ActionBarNavigationCallback implements ActionBar.OnNavigationListener { 236 @Override 237 public boolean onNavigationItemSelected(int itemPosition, long accountId) { 238 if (accountId != mCallback.getUIAccountId()) { 239 mCallback.onAccountSelected(accountId); 240 } 241 return true; 242 } 243 } 244} 245