summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TabHost.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/widget/TabHost.java
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/widget/TabHost.java')
-rw-r--r--core/java/android/widget/TabHost.java632
1 files changed, 0 insertions, 632 deletions
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
deleted file mode 100644
index dc2c70de92e4..000000000000
--- a/core/java/android/widget/TabHost.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.widget;
-
-import android.app.LocalActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.Window;
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container for a tabbed window view. This object holds two children: a set of tab labels that the
- * user clicks to select a specific tab, and a FrameLayout object that displays the contents of that
- * page. The individual elements are typically controlled using this container object, rather than
- * setting values on the child elements themselves.
- */
-public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener {
-
- private TabWidget mTabWidget;
- private FrameLayout mTabContent;
- private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
- /**
- * This field should be made private, so it is hidden from the SDK.
- * {@hide}
- */
- protected int mCurrentTab = -1;
- private View mCurrentView = null;
- /**
- * This field should be made private, so it is hidden from the SDK.
- * {@hide}
- */
- protected LocalActivityManager mLocalActivityManager = null;
- private OnTabChangeListener mOnTabChangeListener;
- private OnKeyListener mTabKeyListener;
-
- public TabHost(Context context) {
- super(context);
- initTabHost();
- }
-
- public TabHost(Context context, AttributeSet attrs) {
- super(context, attrs);
- initTabHost();
- }
-
- private final void initTabHost() {
- setFocusableInTouchMode(true);
- setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
-
- mCurrentTab = -1;
- mCurrentView = null;
- }
-
- /**
- * Get a new {@link TabSpec} associated with this tab host.
- * @param tag required tag of tab.
- */
- public TabSpec newTabSpec(String tag) {
- return new TabSpec(tag);
- }
-
-
-
- /**
- * <p>Call setup() before adding tabs if loading TabHost using findViewById(). <i><b>However</i></b>: You do
- * not need to call setup() after getTabHost() in {@link android.app.TabActivity TabActivity}.
- * Example:</p>
-<pre>mTabHost = (TabHost)findViewById(R.id.tabhost);
-mTabHost.setup();
-mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
- */
- public void setup() {
- mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
- if (mTabWidget == null) {
- throw new RuntimeException(
- "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
- }
-
- // KeyListener to attach to all tabs. Detects non-navigation keys
- // and relays them to the tab content.
- mTabKeyListener = new OnKeyListener() {
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_ENTER:
- return false;
-
- }
- mTabContent.requestFocus(View.FOCUS_FORWARD);
- return mTabContent.dispatchKeyEvent(event);
- }
-
- };
-
- mTabWidget.setTabSelectionListener(new TabWidget.OnTabSelectionChanged() {
- public void onTabSelectionChanged(int tabIndex, boolean clicked) {
- setCurrentTab(tabIndex);
- if (clicked) {
- mTabContent.requestFocus(View.FOCUS_FORWARD);
- }
- }
- });
-
- mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
- if (mTabContent == null) {
- throw new RuntimeException(
- "Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
- }
- }
-
- /**
- * If you are using {@link TabSpec#setContent(android.content.Intent)}, this
- * must be called since the activityGroup is needed to launch the local activity.
- *
- * This is done for you if you extend {@link android.app.TabActivity}.
- * @param activityGroup Used to launch activities for tab content.
- */
- public void setup(LocalActivityManager activityGroup) {
- setup();
- mLocalActivityManager = activityGroup;
- }
-
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.addOnTouchModeChangeListener(this);
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- final ViewTreeObserver treeObserver = getViewTreeObserver();
- if (treeObserver != null) {
- treeObserver.removeOnTouchModeChangeListener(this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void onTouchModeChanged(boolean isInTouchMode) {
- if (!isInTouchMode) {
- // leaving touch mode.. if nothing has focus, let's give it to
- // the indicator of the current tab
- if (!mCurrentView.hasFocus() || mCurrentView.isFocused()) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
- }
- }
- }
-
- /**
- * Add a tab.
- * @param tabSpec Specifies how to create the indicator and content.
- */
- public void addTab(TabSpec tabSpec) {
-
- if (tabSpec.mIndicatorStrategy == null) {
- throw new IllegalArgumentException("you must specify a way to create the tab indicator.");
- }
-
- if (tabSpec.mContentStrategy == null) {
- throw new IllegalArgumentException("you must specify a way to create the tab content");
- }
- View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView();
- tabIndicator.setOnKeyListener(mTabKeyListener);
- mTabWidget.addView(tabIndicator);
- mTabSpecs.add(tabSpec);
-
- if (mCurrentTab == -1) {
- setCurrentTab(0);
- }
- }
-
-
- /**
- * Removes all tabs from the tab widget associated with this tab host.
- */
- public void clearAllTabs() {
- mTabWidget.removeAllViews();
- initTabHost();
- mTabContent.removeAllViews();
- mTabSpecs.clear();
- requestLayout();
- invalidate();
- }
-
- public TabWidget getTabWidget() {
- return mTabWidget;
- }
-
- public int getCurrentTab() {
- return mCurrentTab;
- }
-
- public String getCurrentTabTag() {
- if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
- return mTabSpecs.get(mCurrentTab).getTag();
- }
- return null;
- }
-
- public View getCurrentTabView() {
- if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
- return mTabWidget.getChildAt(mCurrentTab);
- }
- return null;
- }
-
- public View getCurrentView() {
- return mCurrentView;
- }
-
- public void setCurrentTabByTag(String tag) {
- int i;
- for (i = 0; i < mTabSpecs.size(); i++) {
- if (mTabSpecs.get(i).getTag().equals(tag)) {
- setCurrentTab(i);
- break;
- }
- }
- }
-
- /**
- * Get the FrameLayout which holds tab content
- */
- public FrameLayout getTabContentView() {
- return mTabContent;
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- final boolean handled = super.dispatchKeyEvent(event);
-
- // unhandled key ups change focus to tab indicator for embedded activities
- // when there is nothing that will take focus from default focus searching
- if (!handled
- && (event.getAction() == KeyEvent.ACTION_DOWN)
- && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP)
- && (mCurrentView.isRootNamespace())
- && (mCurrentView.hasFocus())
- && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
- playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
- return true;
- }
- return handled;
- }
-
-
- @Override
- public void dispatchWindowFocusChanged(boolean hasFocus) {
- mCurrentView.dispatchWindowFocusChanged(hasFocus);
- }
-
- public void setCurrentTab(int index) {
- if (index < 0 || index >= mTabSpecs.size()) {
- return;
- }
-
- if (index == mCurrentTab) {
- return;
- }
-
- // notify old tab content
- if (mCurrentTab != -1) {
- mTabSpecs.get(mCurrentTab).mContentStrategy.tabClosed();
- }
-
- mCurrentTab = index;
- final TabHost.TabSpec spec = mTabSpecs.get(index);
-
- // Call the tab widget's focusCurrentTab(), instead of just
- // selecting the tab.
- mTabWidget.focusCurrentTab(mCurrentTab);
-
- // tab content
- mCurrentView = spec.mContentStrategy.getContentView();
-
- if (mCurrentView.getParent() == null) {
- mTabContent
- .addView(
- mCurrentView,
- new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT));
- }
-
- if (!mTabWidget.hasFocus()) {
- // if the tab widget didn't take focus (likely because we're in touch mode)
- // give the current tab content view a shot
- mCurrentView.requestFocus();
- }
-
- //mTabContent.requestFocus(View.FOCUS_FORWARD);
- invokeOnTabChangeListener();
- }
-
- /**
- * Register a callback to be invoked when the selected state of any of the items
- * in this list changes
- * @param l
- * The callback that will run
- */
- public void setOnTabChangedListener(OnTabChangeListener l) {
- mOnTabChangeListener = l;
- }
-
- private void invokeOnTabChangeListener() {
- if (mOnTabChangeListener != null) {
- mOnTabChangeListener.onTabChanged(getCurrentTabTag());
- }
- }
-
- /**
- * Interface definition for a callback to be invoked when tab changed
- */
- public interface OnTabChangeListener {
- void onTabChanged(String tabId);
- }
-
-
- /**
- * Makes the content of a tab when it is selected. Use this if your tab
- * content needs to be created on demand, i.e. you are not showing an
- * existing view or starting an activity.
- */
- public interface TabContentFactory {
- /**
- * Callback to make the tab contents
- *
- * @param tag
- * Which tab was selected.
- * @return The view to distplay the contents of the selected tab.
- */
- View createTabContent(String tag);
- }
-
-
- /**
- * A tab has a tab indictor, content, and a tag that is used to keep
- * track of it. This builder helps choose among these options.
- *
- * For the tab indicator, your choices are:
- * 1) set a label
- * 2) set a label and an icon
- *
- * For the tab content, your choices are:
- * 1) the id of a {@link View}
- * 2) a {@link TabContentFactory} that creates the {@link View} content.
- * 3) an {@link Intent} that launches an {@link android.app.Activity}.
- */
- public class TabSpec {
-
- private String mTag;
-
- private IndicatorStrategy mIndicatorStrategy;
- private ContentStrategy mContentStrategy;
-
- private TabSpec(String tag) {
- mTag = tag;
- }
-
- /**
- * Specify a label as the tab indicator.
- */
- public TabSpec setIndicator(CharSequence label) {
- mIndicatorStrategy = new LabelIndicatorStrategy(label);
- return this;
- }
-
- /**
- * Specify a label and icon as the tab indicator.
- */
- public TabSpec setIndicator(CharSequence label, Drawable icon) {
- mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon);
- return this;
- }
-
- /**
- * Specify the id of the view that should be used as the content
- * of the tab.
- */
- public TabSpec setContent(int viewId) {
- mContentStrategy = new ViewIdContentStrategy(viewId);
- return this;
- }
-
- /**
- * Specify a {@link android.widget.TabHost.TabContentFactory} to use to
- * create the content of the tab.
- */
- public TabSpec setContent(TabContentFactory contentFactory) {
- mContentStrategy = new FactoryContentStrategy(mTag, contentFactory);
- return this;
- }
-
- /**
- * Specify an intent to use to launch an activity as the tab content.
- */
- public TabSpec setContent(Intent intent) {
- mContentStrategy = new IntentContentStrategy(mTag, intent);
- return this;
- }
-
-
- String getTag() {
- return mTag;
- }
- }
-
- /**
- * Specifies what you do to create a tab indicator.
- */
- private static interface IndicatorStrategy {
-
- /**
- * Return the view for the indicator.
- */
- View createIndicatorView();
- }
-
- /**
- * Specifies what you do to manage the tab content.
- */
- private static interface ContentStrategy {
-
- /**
- * Return the content view. The view should may be cached locally.
- */
- View getContentView();
-
- /**
- * Perhaps do something when the tab associated with this content has
- * been closed (i.e make it invisible, or remove it).
- */
- void tabClosed();
- }
-
- /**
- * How to create a tab indicator that just has a label.
- */
- private class LabelIndicatorStrategy implements IndicatorStrategy {
-
- private final CharSequence mLabel;
-
- private LabelIndicatorStrategy(CharSequence label) {
- mLabel = label;
- }
-
- public View createIndicatorView() {
- LayoutInflater inflater =
- (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View tabIndicator = inflater.inflate(R.layout.tab_indicator,
- mTabWidget, // tab widget is the parent
- false); // no inflate params
-
- final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
- tv.setText(mLabel);
-
- return tabIndicator;
- }
- }
-
- /**
- * How we create a tab indicator that has a label and an icon
- */
- private class LabelAndIconIndicatorStrategy implements IndicatorStrategy {
-
- private final CharSequence mLabel;
- private final Drawable mIcon;
-
- private LabelAndIconIndicatorStrategy(CharSequence label, Drawable icon) {
- mLabel = label;
- mIcon = icon;
- }
-
- public View createIndicatorView() {
- LayoutInflater inflater =
- (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View tabIndicator = inflater.inflate(R.layout.tab_indicator,
- mTabWidget, // tab widget is the parent
- false); // no inflate params
-
- final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
- tv.setText(mLabel);
-
- final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
- iconView.setImageDrawable(mIcon);
-
- return tabIndicator;
- }
- }
-
- /**
- * How to create the tab content via a view id.
- */
- private class ViewIdContentStrategy implements ContentStrategy {
-
- private final View mView;
-
- private ViewIdContentStrategy(int viewId) {
- mView = mTabContent.findViewById(viewId);
- if (mView != null) {
- mView.setVisibility(View.GONE);
- } else {
- throw new RuntimeException("Could not create tab content because " +
- "could not find view with id " + viewId);
- }
- }
-
- public View getContentView() {
- mView.setVisibility(View.VISIBLE);
- return mView;
- }
-
- public void tabClosed() {
- mView.setVisibility(View.GONE);
- }
- }
-
- /**
- * How tab content is managed using {@link TabContentFactory}.
- */
- private class FactoryContentStrategy implements ContentStrategy {
- private View mTabContent;
- private final CharSequence mTag;
- private TabContentFactory mFactory;
-
- public FactoryContentStrategy(CharSequence tag, TabContentFactory factory) {
- mTag = tag;
- mFactory = factory;
- }
-
- public View getContentView() {
- if (mTabContent == null) {
- mTabContent = mFactory.createTabContent(mTag.toString());
- }
- mTabContent.setVisibility(View.VISIBLE);
- return mTabContent;
- }
-
- public void tabClosed() {
- mTabContent.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * How tab content is managed via an {@link Intent}: the content view is the
- * decorview of the launched activity.
- */
- private class IntentContentStrategy implements ContentStrategy {
-
- private final String mTag;
- private final Intent mIntent;
-
- private View mLaunchedView;
-
- private IntentContentStrategy(String tag, Intent intent) {
- mTag = tag;
- mIntent = intent;
- }
-
- public View getContentView() {
- if (mLocalActivityManager == null) {
- throw new IllegalStateException("Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?");
- }
- final Window w = mLocalActivityManager.startActivity(
- mTag, mIntent);
- final View wd = w != null ? w.getDecorView() : null;
- if (mLaunchedView != wd && mLaunchedView != null) {
- if (mLaunchedView.getParent() != null) {
- mTabContent.removeView(mLaunchedView);
- }
- }
- mLaunchedView = wd;
-
- // XXX Set FOCUS_AFTER_DESCENDANTS on embedded activies for now so they can get
- // focus if none of their children have it. They need focus to be able to
- // display menu items.
- //
- // Replace this with something better when Bug 628886 is fixed...
- //
- if (mLaunchedView != null) {
- mLaunchedView.setVisibility(View.VISIBLE);
- mLaunchedView.setFocusableInTouchMode(true);
- ((ViewGroup) mLaunchedView).setDescendantFocusability(
- FOCUS_AFTER_DESCENDANTS);
- }
- return mLaunchedView;
- }
-
- public void tabClosed() {
- if (mLaunchedView != null) {
- mLaunchedView.setVisibility(View.GONE);
- }
- }
- }
-
-}