blob: 20402a33630693a2a3a0e348338044bc0a444229 [file] [log] [blame]
Adam Powell89e06452010-06-23 20:24:52 -07001/*
2 * Copyright (C) 2010 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.internal.app;
18
Adam Powell2c9c9fe2010-07-16 10:17:57 -070019import com.android.internal.view.menu.MenuBuilder;
Adam Powell2c9c9fe2010-07-16 10:17:57 -070020import com.android.internal.view.menu.MenuPopupHelper;
21import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell89e06452010-06-23 20:24:52 -070022import com.android.internal.widget.ActionBarContextView;
23import com.android.internal.widget.ActionBarView;
24
25import android.app.ActionBar;
Adam Powell661c9082010-07-02 10:09:44 -070026import android.app.Activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070027import android.app.Dialog;
Adam Powell661c9082010-07-02 10:09:44 -070028import android.app.Fragment;
29import android.app.FragmentTransaction;
Adam Powelldec9dfd2010-08-09 15:27:54 -070030import android.content.Context;
Adam Powell89e06452010-06-23 20:24:52 -070031import android.graphics.drawable.Drawable;
Adam Powell0e94b512010-06-29 17:58:20 -070032import android.os.Handler;
Adam Powell6e346362010-07-23 10:18:23 -070033import android.view.ActionMode;
Adam Powell32555f32010-11-17 13:49:22 -080034import android.view.LayoutInflater;
Adam Powell89e06452010-06-23 20:24:52 -070035import android.view.Menu;
Adam Powell9168f0b2010-08-02 15:46:24 -070036import android.view.MenuInflater;
Adam Powell89e06452010-06-23 20:24:52 -070037import android.view.MenuItem;
38import android.view.View;
39import android.widget.LinearLayout;
40import android.widget.SpinnerAdapter;
41import android.widget.ViewAnimator;
42
Adam Powell29ed7572010-07-14 16:24:56 -070043import java.lang.ref.WeakReference;
Adam Powell661c9082010-07-02 10:09:44 -070044import java.util.ArrayList;
45
Adam Powell89e06452010-06-23 20:24:52 -070046/**
47 * ActionBarImpl is the ActionBar implementation used
48 * by devices of all screen sizes. If it detects a compatible decor,
49 * it will split contextual modes across both the ActionBarView at
50 * the top of the screen and a horizontal LinearLayout at the bottom
51 * which is normally hidden.
52 */
53public class ActionBarImpl extends ActionBar {
54 private static final int NORMAL_VIEW = 0;
55 private static final int CONTEXT_VIEW = 1;
Adam Powell661c9082010-07-02 10:09:44 -070056
Adam Powelldec9dfd2010-08-09 15:27:54 -070057 private Context mContext;
Adam Powell661c9082010-07-02 10:09:44 -070058 private Activity mActivity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070059 private Dialog mDialog;
Adam Powell661c9082010-07-02 10:09:44 -070060
Adam Powell89e06452010-06-23 20:24:52 -070061 private ViewAnimator mAnimatorView;
62 private ActionBarView mActionView;
63 private ActionBarContextView mUpperContextView;
64 private LinearLayout mLowerContextView;
Adam Powell661c9082010-07-02 10:09:44 -070065
66 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
67
Adam Powell661c9082010-07-02 10:09:44 -070068 private TabImpl mSelectedTab;
Adam Powell0c24a552010-11-03 16:44:11 -070069 private int mSavedTabPosition = INVALID_POSITION;
Adam Powell89e06452010-06-23 20:24:52 -070070
Adam Powell5d279772010-07-27 16:34:07 -070071 private ActionMode mActionMode;
Adam Powell89e06452010-06-23 20:24:52 -070072
73 private static final int CONTEXT_DISPLAY_NORMAL = 0;
74 private static final int CONTEXT_DISPLAY_SPLIT = 1;
75
Adam Powell0c24a552010-11-03 16:44:11 -070076 private static final int INVALID_POSITION = -1;
77
Adam Powell89e06452010-06-23 20:24:52 -070078 private int mContextDisplayMode;
Adam Powell0e94b512010-06-29 17:58:20 -070079
Adam Powell3461b322010-07-14 11:34:43 -070080 private boolean mClosingContext;
81
Adam Powell0e94b512010-06-29 17:58:20 -070082 final Handler mHandler = new Handler();
83 final Runnable mCloseContext = new Runnable() {
84 public void run() {
85 mUpperContextView.closeMode();
86 if (mLowerContextView != null) {
87 mLowerContextView.removeAllViews();
88 }
Adam Powell3461b322010-07-14 11:34:43 -070089 mClosingContext = false;
Adam Powell0e94b512010-06-29 17:58:20 -070090 }
91 };
92
Adam Powell661c9082010-07-02 10:09:44 -070093 public ActionBarImpl(Activity activity) {
Adam Powell661c9082010-07-02 10:09:44 -070094 mActivity = activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070095 init(activity.getWindow().getDecorView());
96 }
97
98 public ActionBarImpl(Dialog dialog) {
99 mDialog = dialog;
100 init(dialog.getWindow().getDecorView());
101 }
102
103 private void init(View decor) {
104 mContext = decor.getContext();
Adam Powell89e06452010-06-23 20:24:52 -0700105 mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
106 mUpperContextView = (ActionBarContextView) decor.findViewById(
107 com.android.internal.R.id.action_context_bar);
108 mLowerContextView = (LinearLayout) decor.findViewById(
109 com.android.internal.R.id.lower_action_context_bar);
110 mAnimatorView = (ViewAnimator) decor.findViewById(
111 com.android.internal.R.id.action_bar_animator);
Steve Block08f194b2010-08-24 18:20:48 +0100112
Adam Powell89e06452010-06-23 20:24:52 -0700113 if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
114 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
115 "with a compatible window decor layout");
116 }
Adam Powell0e94b512010-06-29 17:58:20 -0700117
Steve Block08f194b2010-08-24 18:20:48 +0100118 mActionView.setContextView(mUpperContextView);
Adam Powell89e06452010-06-23 20:24:52 -0700119 mContextDisplayMode = mLowerContextView == null ?
120 CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
121 }
122
Adam Powella66c7b02010-07-28 15:28:25 -0700123 @Override
Adam Powella66c7b02010-07-28 15:28:25 -0700124 public void setTitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700125 setTitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700126 }
127
128 @Override
129 public void setSubtitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700130 setSubtitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700131 }
132
Adam Powell89e06452010-06-23 20:24:52 -0700133 public void setCustomNavigationMode(View view) {
Adam Powell661c9082010-07-02 10:09:44 -0700134 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700135 setCustomView(view);
136 setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
137 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
Adam Powell89e06452010-06-23 20:24:52 -0700138 mActionView.setCallback(null);
139 }
Adam Powell0e94b512010-06-29 17:58:20 -0700140
Adam Powell89e06452010-06-23 20:24:52 -0700141 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
Adam Powell17809772010-07-21 13:25:11 -0700142 setDropdownNavigationMode(adapter, callback, -1);
143 }
144
145 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback,
146 int defaultSelectedPosition) {
Adam Powell661c9082010-07-02 10:09:44 -0700147 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700148 setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
149 mActionView.setNavigationMode(NAVIGATION_MODE_LIST);
150 setListNavigationCallbacks(adapter, callback);
Adam Powell17809772010-07-21 13:25:11 -0700151 if (defaultSelectedPosition >= 0) {
152 mActionView.setDropdownSelectedPosition(defaultSelectedPosition);
153 }
Adam Powell89e06452010-06-23 20:24:52 -0700154 }
Adam Powell0e94b512010-06-29 17:58:20 -0700155
156 public void setStandardNavigationMode() {
Adam Powell661c9082010-07-02 10:09:44 -0700157 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700158 setDisplayOptions(DISPLAY_SHOW_TITLE, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
Adam Powell0e94b512010-06-29 17:58:20 -0700159 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
160 mActionView.setCallback(null);
161 }
162
Adam Powell17809772010-07-21 13:25:11 -0700163 public void setSelectedNavigationItem(int position) {
164 switch (mActionView.getNavigationMode()) {
165 case NAVIGATION_MODE_TABS:
166 selectTab(mTabs.get(position));
167 break;
Adam Powell9ab97872010-10-26 21:47:29 -0700168 case NAVIGATION_MODE_LIST:
Adam Powell17809772010-07-21 13:25:11 -0700169 mActionView.setDropdownSelectedPosition(position);
170 break;
171 default:
172 throw new IllegalStateException(
Adam Powell9ab97872010-10-26 21:47:29 -0700173 "setSelectedNavigationIndex not valid for current navigation mode");
Adam Powell17809772010-07-21 13:25:11 -0700174 }
175 }
176
177 public int getSelectedNavigationItem() {
Adam Powell9ab97872010-10-26 21:47:29 -0700178 return getSelectedNavigationIndex();
179 }
180
181 public void removeAllTabs() {
182 cleanupTabs();
Adam Powell17809772010-07-21 13:25:11 -0700183 }
184
Adam Powell661c9082010-07-02 10:09:44 -0700185 private void cleanupTabs() {
186 if (mSelectedTab != null) {
187 selectTab(null);
188 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700189 mTabs.clear();
Adam Powell0c24a552010-11-03 16:44:11 -0700190 mActionView.removeAllTabs();
191 mSavedTabPosition = INVALID_POSITION;
Adam Powell661c9082010-07-02 10:09:44 -0700192 }
193
Adam Powell0e94b512010-06-29 17:58:20 -0700194 public void setTitle(CharSequence title) {
195 mActionView.setTitle(title);
196 }
197
198 public void setSubtitle(CharSequence subtitle) {
199 mActionView.setSubtitle(subtitle);
200 }
201
Adam Powell89e06452010-06-23 20:24:52 -0700202 public void setDisplayOptions(int options) {
203 mActionView.setDisplayOptions(options);
204 }
Adam Powell0e94b512010-06-29 17:58:20 -0700205
Adam Powell89e06452010-06-23 20:24:52 -0700206 public void setDisplayOptions(int options, int mask) {
207 final int current = mActionView.getDisplayOptions();
208 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
209 }
210
211 public void setBackgroundDrawable(Drawable d) {
212 mActionView.setBackgroundDrawable(d);
213 }
214
215 public View getCustomNavigationView() {
Adam Powellef704442010-11-16 14:48:22 -0800216 return getCustomView();
217 }
218
219 public View getCustomView() {
Adam Powell89e06452010-06-23 20:24:52 -0700220 return mActionView.getCustomNavigationView();
221 }
222
223 public CharSequence getTitle() {
224 return mActionView.getTitle();
225 }
226
227 public CharSequence getSubtitle() {
228 return mActionView.getSubtitle();
229 }
230
231 public int getNavigationMode() {
232 return mActionView.getNavigationMode();
233 }
234
235 public int getDisplayOptions() {
236 return mActionView.getDisplayOptions();
237 }
238
Adam Powell5d279772010-07-27 16:34:07 -0700239 public ActionMode startActionMode(ActionMode.Callback callback) {
240 if (mActionMode != null) {
241 mActionMode.finish();
Adam Powell6e346362010-07-23 10:18:23 -0700242 }
Adam Powell3461b322010-07-14 11:34:43 -0700243
244 // Don't wait for the close context mode animation to finish.
245 if (mClosingContext) {
246 mAnimatorView.clearAnimation();
247 mHandler.removeCallbacks(mCloseContext);
248 mCloseContext.run();
249 }
250
Adam Powell5d279772010-07-27 16:34:07 -0700251 ActionMode mode = new ActionModeImpl(callback);
Adam Powell6e346362010-07-23 10:18:23 -0700252 if (callback.onCreateActionMode(mode, mode.getMenu())) {
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700253 mode.invalidate();
254 mUpperContextView.initForMode(mode);
Adam Powell89e06452010-06-23 20:24:52 -0700255 mAnimatorView.setDisplayedChild(CONTEXT_VIEW);
256 if (mLowerContextView != null) {
257 // TODO animate this
258 mLowerContextView.setVisibility(View.VISIBLE);
259 }
Adam Powell5d279772010-07-27 16:34:07 -0700260 mActionMode = mode;
Adam Powellac695c62010-07-20 18:19:27 -0700261 return mode;
Adam Powell89e06452010-06-23 20:24:52 -0700262 }
Adam Powellac695c62010-07-20 18:19:27 -0700263 return null;
Adam Powell89e06452010-06-23 20:24:52 -0700264 }
265
Adam Powell661c9082010-07-02 10:09:44 -0700266 private void configureTab(Tab tab, int position) {
267 final TabImpl tabi = (TabImpl) tab;
Adam Powell2b6230e2010-09-07 17:55:25 -0700268 final ActionBar.TabListener callback = tabi.getCallback();
269
270 if (callback == null) {
271 throw new IllegalStateException("Action Bar Tab must have a Callback");
272 }
Adam Powell661c9082010-07-02 10:09:44 -0700273
274 tabi.setPosition(position);
275 mTabs.add(position, tabi);
276
Adam Powell81b89442010-11-02 17:58:56 -0700277 final int count = mTabs.size();
278 for (int i = position + 1; i < count; i++) {
279 mTabs.get(i).setPosition(i);
Adam Powell661c9082010-07-02 10:09:44 -0700280 }
Adam Powell661c9082010-07-02 10:09:44 -0700281 }
282
283 @Override
284 public void addTab(Tab tab) {
Adam Powell81b89442010-11-02 17:58:56 -0700285 addTab(tab, mTabs.isEmpty());
Adam Powell661c9082010-07-02 10:09:44 -0700286 }
287
288 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700289 public void addTab(Tab tab, int position) {
Adam Powell81b89442010-11-02 17:58:56 -0700290 addTab(tab, position, mTabs.isEmpty());
291 }
292
293 @Override
294 public void addTab(Tab tab, boolean setSelected) {
295 mActionView.addTab(tab, setSelected);
296 configureTab(tab, mTabs.size());
297 if (setSelected) {
298 selectTab(tab);
299 }
300 }
301
302 @Override
303 public void addTab(Tab tab, int position, boolean setSelected) {
304 mActionView.addTab(tab, position, setSelected);
Adam Powell661c9082010-07-02 10:09:44 -0700305 configureTab(tab, position);
Adam Powell81b89442010-11-02 17:58:56 -0700306 if (setSelected) {
307 selectTab(tab);
308 }
Adam Powell661c9082010-07-02 10:09:44 -0700309 }
310
311 @Override
312 public Tab newTab() {
313 return new TabImpl();
314 }
315
316 @Override
317 public void removeTab(Tab tab) {
318 removeTabAt(tab.getPosition());
319 }
320
321 @Override
322 public void removeTabAt(int position) {
Adam Powell0c24a552010-11-03 16:44:11 -0700323 int selectedTabPosition = mSelectedTab != null
324 ? mSelectedTab.getPosition() : mSavedTabPosition;
Adam Powell661c9082010-07-02 10:09:44 -0700325 mActionView.removeTabAt(position);
326 mTabs.remove(position);
327
328 final int newTabCount = mTabs.size();
329 for (int i = position; i < newTabCount; i++) {
330 mTabs.get(i).setPosition(i);
331 }
332
Adam Powell0c24a552010-11-03 16:44:11 -0700333 if (selectedTabPosition == position) {
334 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
335 }
Adam Powell661c9082010-07-02 10:09:44 -0700336 }
337
338 @Override
339 public void setTabNavigationMode() {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700340 if (mActivity == null) {
341 throw new IllegalStateException(
342 "Tab navigation mode cannot be used outside of an Activity");
343 }
Adam Powell9ab97872010-10-26 21:47:29 -0700344 setDisplayOptions(0, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
Adam Powell661c9082010-07-02 10:09:44 -0700345 mActionView.setNavigationMode(NAVIGATION_MODE_TABS);
346 }
347
348 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700349 public void selectTab(Tab tab) {
Adam Powell0c24a552010-11-03 16:44:11 -0700350 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
351 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
352 return;
353 }
354
355 final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction()
356 .disallowAddToBackStack();
Adam Powell7f9b9052010-10-19 16:56:07 -0700357
358 if (mSelectedTab == tab) {
359 if (mSelectedTab != null) {
360 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
361 }
362 } else {
363 mActionView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
364 if (mSelectedTab != null) {
365 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
366 }
367 mSelectedTab = (TabImpl) tab;
368 if (mSelectedTab != null) {
369 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
370 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700371 }
372
373 if (!trans.isEmpty()) {
374 trans.commit();
375 }
376 }
377
378 @Override
379 public Tab getSelectedTab() {
380 return mSelectedTab;
Adam Powell661c9082010-07-02 10:09:44 -0700381 }
382
Adam Powell6b336f82010-08-10 20:13:01 -0700383 @Override
384 public int getHeight() {
385 return mActionView.getHeight();
386 }
387
388 @Override
389 public void show() {
390 // TODO animate!
391 mAnimatorView.setVisibility(View.VISIBLE);
392 }
393
394 @Override
395 public void hide() {
396 // TODO animate!
397 mAnimatorView.setVisibility(View.GONE);
398 }
399
400 public boolean isShowing() {
401 return mAnimatorView.getVisibility() == View.VISIBLE;
402 }
403
Adam Powell89e06452010-06-23 20:24:52 -0700404 /**
405 * @hide
406 */
Adam Powell5d279772010-07-27 16:34:07 -0700407 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
Adam Powell6e346362010-07-23 10:18:23 -0700408 private ActionMode.Callback mCallback;
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700409 private MenuBuilder mMenu;
Adam Powell29ed7572010-07-14 16:24:56 -0700410 private WeakReference<View> mCustomView;
Adam Powell89e06452010-06-23 20:24:52 -0700411
Adam Powell5d279772010-07-27 16:34:07 -0700412 public ActionModeImpl(ActionMode.Callback callback) {
Adam Powell89e06452010-06-23 20:24:52 -0700413 mCallback = callback;
Adam Powell4d9861e2010-08-17 11:14:40 -0700414 mMenu = new MenuBuilder(mActionView.getContext())
415 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700416 mMenu.setCallback(this);
Adam Powell89e06452010-06-23 20:24:52 -0700417 }
Adam Powell9168f0b2010-08-02 15:46:24 -0700418
419 @Override
420 public MenuInflater getMenuInflater() {
Adam Powell4d9861e2010-08-17 11:14:40 -0700421 return new MenuInflater(mContext);
Adam Powell9168f0b2010-08-02 15:46:24 -0700422 }
423
Adam Powell89e06452010-06-23 20:24:52 -0700424 @Override
425 public Menu getMenu() {
426 return mMenu;
427 }
428
429 @Override
430 public void finish() {
Adam Powell5d279772010-07-27 16:34:07 -0700431 if (mActionMode != this) {
432 // Not the active action mode - no-op
Adam Powell93b6bc32010-07-22 11:36:35 -0700433 return;
434 }
435
Adam Powell6e346362010-07-23 10:18:23 -0700436 mCallback.onDestroyActionMode(this);
Adam Powell89e06452010-06-23 20:24:52 -0700437 mAnimatorView.setDisplayedChild(NORMAL_VIEW);
Adam Powell0e94b512010-06-29 17:58:20 -0700438
439 // Clear out the context mode views after the animation finishes
Adam Powell3461b322010-07-14 11:34:43 -0700440 mClosingContext = true;
Adam Powell0e94b512010-06-29 17:58:20 -0700441 mHandler.postDelayed(mCloseContext, mAnimatorView.getOutAnimation().getDuration());
442
Adam Powell89e06452010-06-23 20:24:52 -0700443 if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
444 // TODO Animate this
445 mLowerContextView.setVisibility(View.GONE);
446 }
Adam Powell5d279772010-07-27 16:34:07 -0700447 mActionMode = null;
Adam Powell89e06452010-06-23 20:24:52 -0700448 }
449
450 @Override
451 public void invalidate() {
Adam Powell6e346362010-07-23 10:18:23 -0700452 if (mCallback.onPrepareActionMode(this, mMenu)) {
Adam Powell89e06452010-06-23 20:24:52 -0700453 // Refresh content in both context views
454 }
455 }
456
457 @Override
458 public void setCustomView(View view) {
459 mUpperContextView.setCustomView(view);
Adam Powell29ed7572010-07-14 16:24:56 -0700460 mCustomView = new WeakReference<View>(view);
Adam Powell89e06452010-06-23 20:24:52 -0700461 }
462
463 @Override
464 public void setSubtitle(CharSequence subtitle) {
465 mUpperContextView.setSubtitle(subtitle);
466 }
467
468 @Override
469 public void setTitle(CharSequence title) {
470 mUpperContextView.setTitle(title);
471 }
Adam Powell29ed7572010-07-14 16:24:56 -0700472
473 @Override
Adam Powellc9ae2a22010-07-28 14:44:21 -0700474 public void setTitle(int resId) {
475 setTitle(mActivity.getString(resId));
476 }
477
478 @Override
479 public void setSubtitle(int resId) {
480 setSubtitle(mActivity.getString(resId));
481 }
482
483 @Override
Adam Powell29ed7572010-07-14 16:24:56 -0700484 public CharSequence getTitle() {
485 return mUpperContextView.getTitle();
486 }
487
488 @Override
489 public CharSequence getSubtitle() {
490 return mUpperContextView.getSubtitle();
491 }
Adam Powell89e06452010-06-23 20:24:52 -0700492
Adam Powell29ed7572010-07-14 16:24:56 -0700493 @Override
494 public View getCustomView() {
495 return mCustomView != null ? mCustomView.get() : null;
496 }
497
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700498 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Adam Powell6e346362010-07-23 10:18:23 -0700499 return mCallback.onActionItemClicked(this, item);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700500 }
501
502 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
503 }
504
505 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
506 if (!subMenu.hasVisibleItems()) {
507 return true;
Adam Powell89e06452010-06-23 20:24:52 -0700508 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700509
Adam Powelldec9dfd2010-08-09 15:27:54 -0700510 new MenuPopupHelper(mContext, subMenu).show();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700511 return true;
512 }
513
514 public void onCloseSubMenu(SubMenuBuilder menu) {
515 }
516
517 public void onMenuModeChange(MenuBuilder menu) {
Adam Powellf6148c52010-08-11 21:10:16 -0700518 invalidate();
519 mUpperContextView.showOverflowMenu();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700520 }
Adam Powell661c9082010-07-02 10:09:44 -0700521 }
522
523 /**
524 * @hide
525 */
526 public class TabImpl extends ActionBar.Tab {
Adam Powell2b6230e2010-09-07 17:55:25 -0700527 private ActionBar.TabListener mCallback;
528 private Object mTag;
Adam Powell661c9082010-07-02 10:09:44 -0700529 private Drawable mIcon;
530 private CharSequence mText;
531 private int mPosition;
Adam Powell2b6230e2010-09-07 17:55:25 -0700532 private View mCustomView;
Adam Powell661c9082010-07-02 10:09:44 -0700533
534 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700535 public Object getTag() {
536 return mTag;
537 }
538
539 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700540 public Tab setTag(Object tag) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700541 mTag = tag;
Adam Powell9ab97872010-10-26 21:47:29 -0700542 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700543 }
544
545 public ActionBar.TabListener getCallback() {
546 return mCallback;
547 }
548
549 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700550 public Tab setTabListener(ActionBar.TabListener callback) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700551 mCallback = callback;
Adam Powell9ab97872010-10-26 21:47:29 -0700552 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700553 }
554
555 @Override
556 public View getCustomView() {
557 return mCustomView;
558 }
559
560 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700561 public Tab setCustomView(View view) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700562 mCustomView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700563 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700564 }
565
566 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800567 public Tab setCustomView(int layoutResId) {
568 return setCustomView(LayoutInflater.from(mContext).inflate(layoutResId, null));
569 }
570
571 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700572 public Drawable getIcon() {
573 return mIcon;
574 }
575
576 @Override
577 public int getPosition() {
578 return mPosition;
579 }
580
581 public void setPosition(int position) {
582 mPosition = position;
583 }
584
585 @Override
586 public CharSequence getText() {
587 return mText;
588 }
589
590 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700591 public Tab setIcon(Drawable icon) {
Adam Powell661c9082010-07-02 10:09:44 -0700592 mIcon = icon;
Adam Powell9ab97872010-10-26 21:47:29 -0700593 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700594 }
595
596 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800597 public Tab setIcon(int resId) {
598 return setIcon(mContext.getResources().getDrawable(resId));
599 }
600
601 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700602 public Tab setText(CharSequence text) {
Adam Powell661c9082010-07-02 10:09:44 -0700603 mText = text;
Adam Powell9ab97872010-10-26 21:47:29 -0700604 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700605 }
606
607 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800608 public Tab setText(int resId) {
609 return setText(mContext.getResources().getText(resId));
610 }
611
612 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700613 public void select() {
614 selectTab(this);
Adam Powell89e06452010-06-23 20:24:52 -0700615 }
616 }
Adam Powell9ab97872010-10-26 21:47:29 -0700617
618 @Override
619 public void setCustomView(View view) {
620 mActionView.setCustomNavigationView(view);
621 }
622
623 @Override
624 public void setCustomView(View view, LayoutParams layoutParams) {
625 view.setLayoutParams(layoutParams);
626 mActionView.setCustomNavigationView(view);
627 }
628
629 @Override
630 public void setListNavigationCallbacks(SpinnerAdapter adapter, NavigationCallback callback) {
631 mActionView.setDropdownAdapter(adapter);
632 mActionView.setCallback(callback);
633 }
634
635 @Override
636 public int getSelectedNavigationIndex() {
637 switch (mActionView.getNavigationMode()) {
638 case NAVIGATION_MODE_TABS:
Adam Powell04587962010-11-11 22:15:07 -0800639 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
Adam Powell9ab97872010-10-26 21:47:29 -0700640 case NAVIGATION_MODE_LIST:
641 return mActionView.getDropdownSelectedPosition();
642 default:
643 return -1;
644 }
645 }
646
647 @Override
648 public int getNavigationItemCount() {
649 switch (mActionView.getNavigationMode()) {
650 case NAVIGATION_MODE_TABS:
651 return mTabs.size();
652 case NAVIGATION_MODE_LIST:
653 SpinnerAdapter adapter = mActionView.getDropdownAdapter();
654 return adapter != null ? adapter.getCount() : 0;
655 default:
656 return 0;
657 }
658 }
659
660 @Override
Adam Powell0c24a552010-11-03 16:44:11 -0700661 public int getTabCount() {
662 return mTabs.size();
663 }
664
665 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700666 public void setNavigationMode(int mode) {
Adam Powell0c24a552010-11-03 16:44:11 -0700667 final int oldMode = mActionView.getNavigationMode();
668 switch (oldMode) {
669 case NAVIGATION_MODE_TABS:
670 mSavedTabPosition = getSelectedNavigationIndex();
671 selectTab(null);
672 break;
673 }
Adam Powell9ab97872010-10-26 21:47:29 -0700674 mActionView.setNavigationMode(mode);
Adam Powell0c24a552010-11-03 16:44:11 -0700675 switch (mode) {
676 case NAVIGATION_MODE_TABS:
677 if (mSavedTabPosition != INVALID_POSITION) {
678 setSelectedNavigationItem(mSavedTabPosition);
679 mSavedTabPosition = INVALID_POSITION;
680 }
681 break;
682 }
Adam Powell9ab97872010-10-26 21:47:29 -0700683 }
684
685 @Override
686 public Tab getTabAt(int index) {
687 return mTabs.get(index);
688 }
Adam Powell0c24a552010-11-03 16:44:11 -0700689
690 /**
691 * This fragment is added when we're keeping a back stack in a tab switch
692 * transaction. We use it to change the selected tab in the action bar view
693 * when we back out.
694 */
695 private class SwitchSelectedTabViewFragment extends Fragment {
696 private int mSelectedTabIndex;
697
698 public SwitchSelectedTabViewFragment(int oldSelectedTab) {
699 mSelectedTabIndex = oldSelectedTab;
700 }
701
702 @Override
703 public void onDetach() {
704 if (mSelectedTabIndex >= 0 && mSelectedTabIndex < getTabCount()) {
705 mActionView.setTabSelected(mSelectedTabIndex);
706 }
707 }
708 }
Adam Powell89e06452010-06-23 20:24:52 -0700709}