blob: 86523acdc78c7744558846136d3ebed9040d28fa [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 Powell89e06452010-06-23 20:24:52 -070034import android.view.Menu;
Adam Powell9168f0b2010-08-02 15:46:24 -070035import android.view.MenuInflater;
Adam Powell89e06452010-06-23 20:24:52 -070036import android.view.MenuItem;
37import android.view.View;
38import android.widget.LinearLayout;
39import android.widget.SpinnerAdapter;
40import android.widget.ViewAnimator;
41
Adam Powell29ed7572010-07-14 16:24:56 -070042import java.lang.ref.WeakReference;
Adam Powell661c9082010-07-02 10:09:44 -070043import java.util.ArrayList;
44
Adam Powell89e06452010-06-23 20:24:52 -070045/**
46 * ActionBarImpl is the ActionBar implementation used
47 * by devices of all screen sizes. If it detects a compatible decor,
48 * it will split contextual modes across both the ActionBarView at
49 * the top of the screen and a horizontal LinearLayout at the bottom
50 * which is normally hidden.
51 */
52public class ActionBarImpl extends ActionBar {
53 private static final int NORMAL_VIEW = 0;
54 private static final int CONTEXT_VIEW = 1;
Adam Powell661c9082010-07-02 10:09:44 -070055
Adam Powelldec9dfd2010-08-09 15:27:54 -070056 private Context mContext;
Adam Powell661c9082010-07-02 10:09:44 -070057 private Activity mActivity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070058 private Dialog mDialog;
Adam Powell661c9082010-07-02 10:09:44 -070059
Adam Powell89e06452010-06-23 20:24:52 -070060 private ViewAnimator mAnimatorView;
61 private ActionBarView mActionView;
62 private ActionBarContextView mUpperContextView;
63 private LinearLayout mLowerContextView;
Adam Powell661c9082010-07-02 10:09:44 -070064
65 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
66
Adam Powell661c9082010-07-02 10:09:44 -070067 private TabImpl mSelectedTab;
Adam Powell0c24a552010-11-03 16:44:11 -070068 private int mSavedTabPosition = INVALID_POSITION;
Adam Powell89e06452010-06-23 20:24:52 -070069
Adam Powell5d279772010-07-27 16:34:07 -070070 private ActionMode mActionMode;
Adam Powell89e06452010-06-23 20:24:52 -070071
72 private static final int CONTEXT_DISPLAY_NORMAL = 0;
73 private static final int CONTEXT_DISPLAY_SPLIT = 1;
74
Adam Powell0c24a552010-11-03 16:44:11 -070075 private static final int INVALID_POSITION = -1;
76
Adam Powell89e06452010-06-23 20:24:52 -070077 private int mContextDisplayMode;
Adam Powell0e94b512010-06-29 17:58:20 -070078
Adam Powell3461b322010-07-14 11:34:43 -070079 private boolean mClosingContext;
80
Adam Powell0e94b512010-06-29 17:58:20 -070081 final Handler mHandler = new Handler();
82 final Runnable mCloseContext = new Runnable() {
83 public void run() {
84 mUpperContextView.closeMode();
85 if (mLowerContextView != null) {
86 mLowerContextView.removeAllViews();
87 }
Adam Powell3461b322010-07-14 11:34:43 -070088 mClosingContext = false;
Adam Powell0e94b512010-06-29 17:58:20 -070089 }
90 };
91
Adam Powell661c9082010-07-02 10:09:44 -070092 public ActionBarImpl(Activity activity) {
Adam Powell661c9082010-07-02 10:09:44 -070093 mActivity = activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070094 init(activity.getWindow().getDecorView());
95 }
96
97 public ActionBarImpl(Dialog dialog) {
98 mDialog = dialog;
99 init(dialog.getWindow().getDecorView());
100 }
101
102 private void init(View decor) {
103 mContext = decor.getContext();
Adam Powell89e06452010-06-23 20:24:52 -0700104 mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
105 mUpperContextView = (ActionBarContextView) decor.findViewById(
106 com.android.internal.R.id.action_context_bar);
107 mLowerContextView = (LinearLayout) decor.findViewById(
108 com.android.internal.R.id.lower_action_context_bar);
109 mAnimatorView = (ViewAnimator) decor.findViewById(
110 com.android.internal.R.id.action_bar_animator);
Steve Block08f194b2010-08-24 18:20:48 +0100111
Adam Powell89e06452010-06-23 20:24:52 -0700112 if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
113 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
114 "with a compatible window decor layout");
115 }
Adam Powell0e94b512010-06-29 17:58:20 -0700116
Steve Block08f194b2010-08-24 18:20:48 +0100117 mActionView.setContextView(mUpperContextView);
Adam Powell89e06452010-06-23 20:24:52 -0700118 mContextDisplayMode = mLowerContextView == null ?
119 CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
120 }
121
Adam Powella66c7b02010-07-28 15:28:25 -0700122 @Override
Adam Powella66c7b02010-07-28 15:28:25 -0700123 public void setTitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700124 setTitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700125 }
126
127 @Override
128 public void setSubtitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700129 setSubtitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700130 }
131
Adam Powell89e06452010-06-23 20:24:52 -0700132 public void setCustomNavigationMode(View view) {
Adam Powell661c9082010-07-02 10:09:44 -0700133 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700134 setCustomView(view);
135 setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
136 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
Adam Powell89e06452010-06-23 20:24:52 -0700137 mActionView.setCallback(null);
138 }
Adam Powell0e94b512010-06-29 17:58:20 -0700139
Adam Powell89e06452010-06-23 20:24:52 -0700140 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
Adam Powell17809772010-07-21 13:25:11 -0700141 setDropdownNavigationMode(adapter, callback, -1);
142 }
143
144 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback,
145 int defaultSelectedPosition) {
Adam Powell661c9082010-07-02 10:09:44 -0700146 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700147 setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
148 mActionView.setNavigationMode(NAVIGATION_MODE_LIST);
149 setListNavigationCallbacks(adapter, callback);
Adam Powell17809772010-07-21 13:25:11 -0700150 if (defaultSelectedPosition >= 0) {
151 mActionView.setDropdownSelectedPosition(defaultSelectedPosition);
152 }
Adam Powell89e06452010-06-23 20:24:52 -0700153 }
Adam Powell0e94b512010-06-29 17:58:20 -0700154
155 public void setStandardNavigationMode() {
Adam Powell661c9082010-07-02 10:09:44 -0700156 cleanupTabs();
Adam Powell9ab97872010-10-26 21:47:29 -0700157 setDisplayOptions(DISPLAY_SHOW_TITLE, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
Adam Powell0e94b512010-06-29 17:58:20 -0700158 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
159 mActionView.setCallback(null);
160 }
161
Adam Powell17809772010-07-21 13:25:11 -0700162 public void setSelectedNavigationItem(int position) {
163 switch (mActionView.getNavigationMode()) {
164 case NAVIGATION_MODE_TABS:
165 selectTab(mTabs.get(position));
166 break;
Adam Powell9ab97872010-10-26 21:47:29 -0700167 case NAVIGATION_MODE_LIST:
Adam Powell17809772010-07-21 13:25:11 -0700168 mActionView.setDropdownSelectedPosition(position);
169 break;
170 default:
171 throw new IllegalStateException(
Adam Powell9ab97872010-10-26 21:47:29 -0700172 "setSelectedNavigationIndex not valid for current navigation mode");
Adam Powell17809772010-07-21 13:25:11 -0700173 }
174 }
175
176 public int getSelectedNavigationItem() {
Adam Powell9ab97872010-10-26 21:47:29 -0700177 return getSelectedNavigationIndex();
178 }
179
180 public void removeAllTabs() {
181 cleanupTabs();
Adam Powell17809772010-07-21 13:25:11 -0700182 }
183
Adam Powell661c9082010-07-02 10:09:44 -0700184 private void cleanupTabs() {
185 if (mSelectedTab != null) {
186 selectTab(null);
187 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700188 mTabs.clear();
Adam Powell0c24a552010-11-03 16:44:11 -0700189 mActionView.removeAllTabs();
190 mSavedTabPosition = INVALID_POSITION;
Adam Powell661c9082010-07-02 10:09:44 -0700191 }
192
Adam Powell0e94b512010-06-29 17:58:20 -0700193 public void setTitle(CharSequence title) {
194 mActionView.setTitle(title);
195 }
196
197 public void setSubtitle(CharSequence subtitle) {
198 mActionView.setSubtitle(subtitle);
199 }
200
Adam Powell89e06452010-06-23 20:24:52 -0700201 public void setDisplayOptions(int options) {
202 mActionView.setDisplayOptions(options);
203 }
Adam Powell0e94b512010-06-29 17:58:20 -0700204
Adam Powell89e06452010-06-23 20:24:52 -0700205 public void setDisplayOptions(int options, int mask) {
206 final int current = mActionView.getDisplayOptions();
207 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
208 }
209
210 public void setBackgroundDrawable(Drawable d) {
211 mActionView.setBackgroundDrawable(d);
212 }
213
214 public View getCustomNavigationView() {
Adam Powellef704442010-11-16 14:48:22 -0800215 return getCustomView();
216 }
217
218 public View getCustomView() {
Adam Powell89e06452010-06-23 20:24:52 -0700219 return mActionView.getCustomNavigationView();
220 }
221
222 public CharSequence getTitle() {
223 return mActionView.getTitle();
224 }
225
226 public CharSequence getSubtitle() {
227 return mActionView.getSubtitle();
228 }
229
230 public int getNavigationMode() {
231 return mActionView.getNavigationMode();
232 }
233
234 public int getDisplayOptions() {
235 return mActionView.getDisplayOptions();
236 }
237
Adam Powell5d279772010-07-27 16:34:07 -0700238 public ActionMode startActionMode(ActionMode.Callback callback) {
239 if (mActionMode != null) {
240 mActionMode.finish();
Adam Powell6e346362010-07-23 10:18:23 -0700241 }
Adam Powell3461b322010-07-14 11:34:43 -0700242
243 // Don't wait for the close context mode animation to finish.
244 if (mClosingContext) {
245 mAnimatorView.clearAnimation();
246 mHandler.removeCallbacks(mCloseContext);
247 mCloseContext.run();
248 }
249
Adam Powell5d279772010-07-27 16:34:07 -0700250 ActionMode mode = new ActionModeImpl(callback);
Adam Powell6e346362010-07-23 10:18:23 -0700251 if (callback.onCreateActionMode(mode, mode.getMenu())) {
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700252 mode.invalidate();
253 mUpperContextView.initForMode(mode);
Adam Powell89e06452010-06-23 20:24:52 -0700254 mAnimatorView.setDisplayedChild(CONTEXT_VIEW);
255 if (mLowerContextView != null) {
256 // TODO animate this
257 mLowerContextView.setVisibility(View.VISIBLE);
258 }
Adam Powell5d279772010-07-27 16:34:07 -0700259 mActionMode = mode;
Adam Powellac695c62010-07-20 18:19:27 -0700260 return mode;
Adam Powell89e06452010-06-23 20:24:52 -0700261 }
Adam Powellac695c62010-07-20 18:19:27 -0700262 return null;
Adam Powell89e06452010-06-23 20:24:52 -0700263 }
264
Adam Powell661c9082010-07-02 10:09:44 -0700265 private void configureTab(Tab tab, int position) {
266 final TabImpl tabi = (TabImpl) tab;
Adam Powell2b6230e2010-09-07 17:55:25 -0700267 final ActionBar.TabListener callback = tabi.getCallback();
268
269 if (callback == null) {
270 throw new IllegalStateException("Action Bar Tab must have a Callback");
271 }
Adam Powell661c9082010-07-02 10:09:44 -0700272
273 tabi.setPosition(position);
274 mTabs.add(position, tabi);
275
Adam Powell81b89442010-11-02 17:58:56 -0700276 final int count = mTabs.size();
277 for (int i = position + 1; i < count; i++) {
278 mTabs.get(i).setPosition(i);
Adam Powell661c9082010-07-02 10:09:44 -0700279 }
Adam Powell661c9082010-07-02 10:09:44 -0700280 }
281
282 @Override
283 public void addTab(Tab tab) {
Adam Powell81b89442010-11-02 17:58:56 -0700284 addTab(tab, mTabs.isEmpty());
Adam Powell661c9082010-07-02 10:09:44 -0700285 }
286
287 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700288 public void addTab(Tab tab, int position) {
Adam Powell81b89442010-11-02 17:58:56 -0700289 addTab(tab, position, mTabs.isEmpty());
290 }
291
292 @Override
293 public void addTab(Tab tab, boolean setSelected) {
294 mActionView.addTab(tab, setSelected);
295 configureTab(tab, mTabs.size());
296 if (setSelected) {
297 selectTab(tab);
298 }
299 }
300
301 @Override
302 public void addTab(Tab tab, int position, boolean setSelected) {
303 mActionView.addTab(tab, position, setSelected);
Adam Powell661c9082010-07-02 10:09:44 -0700304 configureTab(tab, position);
Adam Powell81b89442010-11-02 17:58:56 -0700305 if (setSelected) {
306 selectTab(tab);
307 }
Adam Powell661c9082010-07-02 10:09:44 -0700308 }
309
310 @Override
311 public Tab newTab() {
312 return new TabImpl();
313 }
314
315 @Override
316 public void removeTab(Tab tab) {
317 removeTabAt(tab.getPosition());
318 }
319
320 @Override
321 public void removeTabAt(int position) {
Adam Powell0c24a552010-11-03 16:44:11 -0700322 int selectedTabPosition = mSelectedTab != null
323 ? mSelectedTab.getPosition() : mSavedTabPosition;
Adam Powell661c9082010-07-02 10:09:44 -0700324 mActionView.removeTabAt(position);
325 mTabs.remove(position);
326
327 final int newTabCount = mTabs.size();
328 for (int i = position; i < newTabCount; i++) {
329 mTabs.get(i).setPosition(i);
330 }
331
Adam Powell0c24a552010-11-03 16:44:11 -0700332 if (selectedTabPosition == position) {
333 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
334 }
Adam Powell661c9082010-07-02 10:09:44 -0700335 }
336
337 @Override
338 public void setTabNavigationMode() {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700339 if (mActivity == null) {
340 throw new IllegalStateException(
341 "Tab navigation mode cannot be used outside of an Activity");
342 }
Adam Powell9ab97872010-10-26 21:47:29 -0700343 setDisplayOptions(0, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
Adam Powell661c9082010-07-02 10:09:44 -0700344 mActionView.setNavigationMode(NAVIGATION_MODE_TABS);
345 }
346
347 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700348 public void selectTab(Tab tab) {
Adam Powell0c24a552010-11-03 16:44:11 -0700349 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
350 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
351 return;
352 }
353
354 final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction()
355 .disallowAddToBackStack();
Adam Powell7f9b9052010-10-19 16:56:07 -0700356
357 if (mSelectedTab == tab) {
358 if (mSelectedTab != null) {
359 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
360 }
361 } else {
362 mActionView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
363 if (mSelectedTab != null) {
364 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
365 }
366 mSelectedTab = (TabImpl) tab;
367 if (mSelectedTab != null) {
368 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
369 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700370 }
371
372 if (!trans.isEmpty()) {
373 trans.commit();
374 }
375 }
376
377 @Override
378 public Tab getSelectedTab() {
379 return mSelectedTab;
Adam Powell661c9082010-07-02 10:09:44 -0700380 }
381
Adam Powell6b336f82010-08-10 20:13:01 -0700382 @Override
383 public int getHeight() {
384 return mActionView.getHeight();
385 }
386
387 @Override
388 public void show() {
389 // TODO animate!
390 mAnimatorView.setVisibility(View.VISIBLE);
391 }
392
393 @Override
394 public void hide() {
395 // TODO animate!
396 mAnimatorView.setVisibility(View.GONE);
397 }
398
399 public boolean isShowing() {
400 return mAnimatorView.getVisibility() == View.VISIBLE;
401 }
402
Adam Powell89e06452010-06-23 20:24:52 -0700403 /**
404 * @hide
405 */
Adam Powell5d279772010-07-27 16:34:07 -0700406 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
Adam Powell6e346362010-07-23 10:18:23 -0700407 private ActionMode.Callback mCallback;
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700408 private MenuBuilder mMenu;
Adam Powell29ed7572010-07-14 16:24:56 -0700409 private WeakReference<View> mCustomView;
Adam Powell89e06452010-06-23 20:24:52 -0700410
Adam Powell5d279772010-07-27 16:34:07 -0700411 public ActionModeImpl(ActionMode.Callback callback) {
Adam Powell89e06452010-06-23 20:24:52 -0700412 mCallback = callback;
Adam Powell4d9861e2010-08-17 11:14:40 -0700413 mMenu = new MenuBuilder(mActionView.getContext())
414 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700415 mMenu.setCallback(this);
Adam Powell89e06452010-06-23 20:24:52 -0700416 }
Adam Powell9168f0b2010-08-02 15:46:24 -0700417
418 @Override
419 public MenuInflater getMenuInflater() {
Adam Powell4d9861e2010-08-17 11:14:40 -0700420 return new MenuInflater(mContext);
Adam Powell9168f0b2010-08-02 15:46:24 -0700421 }
422
Adam Powell89e06452010-06-23 20:24:52 -0700423 @Override
424 public Menu getMenu() {
425 return mMenu;
426 }
427
428 @Override
429 public void finish() {
Adam Powell5d279772010-07-27 16:34:07 -0700430 if (mActionMode != this) {
431 // Not the active action mode - no-op
Adam Powell93b6bc32010-07-22 11:36:35 -0700432 return;
433 }
434
Adam Powell6e346362010-07-23 10:18:23 -0700435 mCallback.onDestroyActionMode(this);
Adam Powell89e06452010-06-23 20:24:52 -0700436 mAnimatorView.setDisplayedChild(NORMAL_VIEW);
Adam Powell0e94b512010-06-29 17:58:20 -0700437
438 // Clear out the context mode views after the animation finishes
Adam Powell3461b322010-07-14 11:34:43 -0700439 mClosingContext = true;
Adam Powell0e94b512010-06-29 17:58:20 -0700440 mHandler.postDelayed(mCloseContext, mAnimatorView.getOutAnimation().getDuration());
441
Adam Powell89e06452010-06-23 20:24:52 -0700442 if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
443 // TODO Animate this
444 mLowerContextView.setVisibility(View.GONE);
445 }
Adam Powell5d279772010-07-27 16:34:07 -0700446 mActionMode = null;
Adam Powell89e06452010-06-23 20:24:52 -0700447 }
448
449 @Override
450 public void invalidate() {
Adam Powell6e346362010-07-23 10:18:23 -0700451 if (mCallback.onPrepareActionMode(this, mMenu)) {
Adam Powell89e06452010-06-23 20:24:52 -0700452 // Refresh content in both context views
453 }
454 }
455
456 @Override
457 public void setCustomView(View view) {
458 mUpperContextView.setCustomView(view);
Adam Powell29ed7572010-07-14 16:24:56 -0700459 mCustomView = new WeakReference<View>(view);
Adam Powell89e06452010-06-23 20:24:52 -0700460 }
461
462 @Override
463 public void setSubtitle(CharSequence subtitle) {
464 mUpperContextView.setSubtitle(subtitle);
465 }
466
467 @Override
468 public void setTitle(CharSequence title) {
469 mUpperContextView.setTitle(title);
470 }
Adam Powell29ed7572010-07-14 16:24:56 -0700471
472 @Override
Adam Powellc9ae2a22010-07-28 14:44:21 -0700473 public void setTitle(int resId) {
474 setTitle(mActivity.getString(resId));
475 }
476
477 @Override
478 public void setSubtitle(int resId) {
479 setSubtitle(mActivity.getString(resId));
480 }
481
482 @Override
Adam Powell29ed7572010-07-14 16:24:56 -0700483 public CharSequence getTitle() {
484 return mUpperContextView.getTitle();
485 }
486
487 @Override
488 public CharSequence getSubtitle() {
489 return mUpperContextView.getSubtitle();
490 }
Adam Powell89e06452010-06-23 20:24:52 -0700491
Adam Powell29ed7572010-07-14 16:24:56 -0700492 @Override
493 public View getCustomView() {
494 return mCustomView != null ? mCustomView.get() : null;
495 }
496
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700497 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Adam Powell6e346362010-07-23 10:18:23 -0700498 return mCallback.onActionItemClicked(this, item);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700499 }
500
501 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
502 }
503
504 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
505 if (!subMenu.hasVisibleItems()) {
506 return true;
Adam Powell89e06452010-06-23 20:24:52 -0700507 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700508
Adam Powelldec9dfd2010-08-09 15:27:54 -0700509 new MenuPopupHelper(mContext, subMenu).show();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700510 return true;
511 }
512
513 public void onCloseSubMenu(SubMenuBuilder menu) {
514 }
515
516 public void onMenuModeChange(MenuBuilder menu) {
Adam Powellf6148c52010-08-11 21:10:16 -0700517 invalidate();
518 mUpperContextView.showOverflowMenu();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700519 }
Adam Powell661c9082010-07-02 10:09:44 -0700520 }
521
522 /**
523 * @hide
524 */
525 public class TabImpl extends ActionBar.Tab {
Adam Powell2b6230e2010-09-07 17:55:25 -0700526 private ActionBar.TabListener mCallback;
527 private Object mTag;
Adam Powell661c9082010-07-02 10:09:44 -0700528 private Drawable mIcon;
529 private CharSequence mText;
530 private int mPosition;
Adam Powell2b6230e2010-09-07 17:55:25 -0700531 private View mCustomView;
Adam Powell661c9082010-07-02 10:09:44 -0700532
533 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700534 public Object getTag() {
535 return mTag;
536 }
537
538 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700539 public Tab setTag(Object tag) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700540 mTag = tag;
Adam Powell9ab97872010-10-26 21:47:29 -0700541 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700542 }
543
544 public ActionBar.TabListener getCallback() {
545 return mCallback;
546 }
547
548 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700549 public Tab setTabListener(ActionBar.TabListener callback) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700550 mCallback = callback;
Adam Powell9ab97872010-10-26 21:47:29 -0700551 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700552 }
553
554 @Override
555 public View getCustomView() {
556 return mCustomView;
557 }
558
559 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700560 public Tab setCustomView(View view) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700561 mCustomView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700562 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700563 }
564
565 @Override
566 public Drawable getIcon() {
567 return mIcon;
568 }
569
570 @Override
571 public int getPosition() {
572 return mPosition;
573 }
574
575 public void setPosition(int position) {
576 mPosition = position;
577 }
578
579 @Override
580 public CharSequence getText() {
581 return mText;
582 }
583
584 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700585 public Tab setIcon(Drawable icon) {
Adam Powell661c9082010-07-02 10:09:44 -0700586 mIcon = icon;
Adam Powell9ab97872010-10-26 21:47:29 -0700587 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700588 }
589
590 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700591 public Tab setText(CharSequence text) {
Adam Powell661c9082010-07-02 10:09:44 -0700592 mText = text;
Adam Powell9ab97872010-10-26 21:47:29 -0700593 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700594 }
595
596 @Override
597 public void select() {
598 selectTab(this);
Adam Powell89e06452010-06-23 20:24:52 -0700599 }
600 }
Adam Powell9ab97872010-10-26 21:47:29 -0700601
602 @Override
603 public void setCustomView(View view) {
604 mActionView.setCustomNavigationView(view);
605 }
606
607 @Override
608 public void setCustomView(View view, LayoutParams layoutParams) {
609 view.setLayoutParams(layoutParams);
610 mActionView.setCustomNavigationView(view);
611 }
612
613 @Override
614 public void setListNavigationCallbacks(SpinnerAdapter adapter, NavigationCallback callback) {
615 mActionView.setDropdownAdapter(adapter);
616 mActionView.setCallback(callback);
617 }
618
619 @Override
620 public int getSelectedNavigationIndex() {
621 switch (mActionView.getNavigationMode()) {
622 case NAVIGATION_MODE_TABS:
Adam Powell04587962010-11-11 22:15:07 -0800623 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
Adam Powell9ab97872010-10-26 21:47:29 -0700624 case NAVIGATION_MODE_LIST:
625 return mActionView.getDropdownSelectedPosition();
626 default:
627 return -1;
628 }
629 }
630
631 @Override
632 public int getNavigationItemCount() {
633 switch (mActionView.getNavigationMode()) {
634 case NAVIGATION_MODE_TABS:
635 return mTabs.size();
636 case NAVIGATION_MODE_LIST:
637 SpinnerAdapter adapter = mActionView.getDropdownAdapter();
638 return adapter != null ? adapter.getCount() : 0;
639 default:
640 return 0;
641 }
642 }
643
644 @Override
Adam Powell0c24a552010-11-03 16:44:11 -0700645 public int getTabCount() {
646 return mTabs.size();
647 }
648
649 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700650 public void setNavigationMode(int mode) {
Adam Powell0c24a552010-11-03 16:44:11 -0700651 final int oldMode = mActionView.getNavigationMode();
652 switch (oldMode) {
653 case NAVIGATION_MODE_TABS:
654 mSavedTabPosition = getSelectedNavigationIndex();
655 selectTab(null);
656 break;
657 }
Adam Powell9ab97872010-10-26 21:47:29 -0700658 mActionView.setNavigationMode(mode);
Adam Powell0c24a552010-11-03 16:44:11 -0700659 switch (mode) {
660 case NAVIGATION_MODE_TABS:
661 if (mSavedTabPosition != INVALID_POSITION) {
662 setSelectedNavigationItem(mSavedTabPosition);
663 mSavedTabPosition = INVALID_POSITION;
664 }
665 break;
666 }
Adam Powell9ab97872010-10-26 21:47:29 -0700667 }
668
669 @Override
670 public Tab getTabAt(int index) {
671 return mTabs.get(index);
672 }
Adam Powell0c24a552010-11-03 16:44:11 -0700673
674 /**
675 * This fragment is added when we're keeping a back stack in a tab switch
676 * transaction. We use it to change the selected tab in the action bar view
677 * when we back out.
678 */
679 private class SwitchSelectedTabViewFragment extends Fragment {
680 private int mSelectedTabIndex;
681
682 public SwitchSelectedTabViewFragment(int oldSelectedTab) {
683 mSelectedTabIndex = oldSelectedTab;
684 }
685
686 @Override
687 public void onDetach() {
688 if (mSelectedTabIndex >= 0 && mSelectedTabIndex < getTabCount()) {
689 mActionView.setTabSelected(mSelectedTabIndex);
690 }
691 }
692 }
Adam Powell89e06452010-06-23 20:24:52 -0700693}