MyTab

Activity

 

public class MyTabActivity extends ActivityGroup
{

    private MyTabHost mTabHost;
    private String mDefaultTab = null;
    private int mDefaultTabIndex = -1;

    /**
     * Sets the default tab that is the first tab highlighted.
     * 
     * @param tag the name of the default tab
     */
    public void setDefaultTab(String tag)
    {
        mDefaultTab = tag;
        mDefaultTabIndex = -1;
    }

    /**
     * Sets the default tab that is the first tab highlighted.
     * 
     * @param index the index of the default tab
     */
    public void setDefaultTab(int index)
    {
        mDefaultTab = null;
        mDefaultTabIndex = index;
    }

    /**
     * onRestoreInstanceState
     * 
     * @param state Bundle
     * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle)
     */
    @Override
    protected void onRestoreInstanceState(Bundle state)
    {
        super.onRestoreInstanceState(state);
        ensureTabHost();
        String cur = state.getString("currentTab");
        if (cur != null)
        {
            mTabHost.setCurrentTabByTag(cur);
        }
        if (mTabHost.getCurrentTab() < 0)
        {
            if (mDefaultTab != null)
            {
                mTabHost.setCurrentTabByTag(mDefaultTab);
            }
            else if (mDefaultTabIndex >= 0)
            {
                mTabHost.setCurrentTab(mDefaultTabIndex);
            }
        }
    }

    /**
     * 
     * onPostCreate
     * 
     * @param icicle Bundle
     * @see android.app.Activity#onPostCreate(android.os.Bundle)
     */
    @Override
    protected void onPostCreate(Bundle icicle)
    {
        super.onPostCreate(icicle);

        ensureTabHost();

        if (mTabHost.getCurrentTab() == -1)
        {
            mTabHost.setCurrentTab(0);
        }
    }

    /**
     * 
     * onSaveInstanceState
     * 
     * @param outState Bundle
     * @see android.app.ActivityGroup#onSaveInstanceState(android.os.Bundle)
     */
    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        String currentTabTag = mTabHost.getCurrentTabTag();
        if (currentTabTag != null)
        {
            outState.putString("currentTab", currentTabTag);
        }
    }

    /**
     * Updates the screen state (current list and other views) when the content
     * changes.
     * 
     *@see Activity#onContentChanged()
     */
    @Override
    public void onContentChanged()
    {
        super.onContentChanged();
        mTabHost = (MyTabHost) findViewById(R.id.tabhost);

        if (mTabHost == null)
        {
            throw new RuntimeException(
                "Your content must have a TabHost whose id attribute is "
                    + "'R.id.tabhost'");
        }
        mTabHost.setup(getLocalActivityManager());
    }

    private void ensureTabHost()
    {
        if (mTabHost == null)
        {
            this.setContentView(R.layout.tab_content);
        }
    }

    /**
     * 
     * onChildTitleChanged
     * 
     * @param childActivity Activity
     * @param title CharSequence
     * @see android.app.Activity#onChildTitleChanged(android.app.Activity,
     *      java.lang.CharSequence)
     */
    @Override
    protected void onChildTitleChanged(Activity childActivity,
        CharSequence title)
    {
        // Dorky implementation until we can have multiple activities running.
        if (getLocalActivityManager().getCurrentActivity() == childActivity)
        {
            View tabView = mTabHost.getCurrentTabView();
            if (tabView != null && tabView instanceof TextView)
            {
                ((TextView) tabView).setText(title);
            }
        }
    }

    /**
     * Returns the {@link TabHost} the activity is using to host its tabs.
     * 
     * @return the {@link TabHost} the activity is using to host its tabs.
     */
    public MyTabHost getTabHost()
    {
        ensureTabHost();
        return mTabHost;
    }

    /**
     * Returns the {@link TabWidget} the activity is using to draw the actual
     * tabs.
     * 
     * @return the {@link TabWidget} the activity is using to draw the actual
     *         tabs.
     */
    public MyTabWidget getTabWidget()
    {
        return mTabHost.getTabWidgetT();
    }

}

 

 Host:

 

public class MyTabHost extends FrameLayout implements OnTouchModeChangeListener
{

    private MyTabWidget mTabWidget;
    private FrameLayout mTabContent;
    private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);

    /**
     * 子TAB标志
     */
    private boolean isParent = true;

    /**
     * This field should be made private, so it is hidden from the SDK.
     */
    private View mCurrentView = null;

    /**
     * This field should be made private, so it is hidden from the SDK.
     */
    private OnTabChangeListener mOnTabChangeListener;
    private OnKeyListener mTabKeyListener;
    private int mCurrentTab = -1;
    private LocalActivityManager mLocalActivityManager = null;

    /**
     * @param context Context
     */
    public MyTabHost(Context context)
    {
        super(context);
        initTabHost();
    }

    /**
     * @param context Context
     * @param attrs AttributeSet
     */
    public MyTabHost(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        initTabHost();
    }

    private final void initTabHost()
    {
        setFocusableInTouchMode(true);
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);

        mCurrentTab = -1;
        mCurrentView = null;
    }

    /**
     * 
     * newTabSpecT
     * 
     * @param tag String
     * @return TabSpec
     */
    public TabSpec newTabSpecT(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 = (MyTabWidget) findViewById(R.id.tabs);
        if (mTabWidget == null)
        {
            throw new RuntimeException(
                "Your TabHost must have a TabWidget whose id attribute is '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 MyTabWidget.OnTabSelectionChanged()
            {
                public void onTabSelectionChanged(int tabIndex, boolean clicked)
                {
                    setCurrentTab(tabIndex);
                    if (clicked)
                    {
                        mTabContent.requestFocus(View.FOCUS_FORWARD);
                    }
                }
            });

        mTabContent = (FrameLayout) findViewById(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;
    }

    /**
     * 
     * onAttachedToWindow
     * 
     * @see android.widget.TabHost#onAttachedToWindow()
     */
    @Override
    protected void onAttachedToWindow()
    {
        super.onAttachedToWindow();
        final ViewTreeObserver treeObserver = getViewTreeObserver();
        if (treeObserver != null)
        {
            treeObserver.addOnTouchModeChangeListener(this);
        }
    }

    /**
     * 
     * onDetachedFromWindow
     * 
     * @see android.widget.TabHost#onDetachedFromWindow()
     */
    @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);
        // 初始化时,设置默认选中tabIndex = 1;
        if (mCurrentTab == -1)
        {
            setCurrentTab(1);
        }
    }

    /**
     * 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 MyTabWidget getTabWidgetT()
    {
        return mTabWidget;
    }

    public int getCurrentTab()
    {
        return mCurrentTab;
    }

    /**
     * 
     * getCurrentTabTag
     * 
     * @return String
     * @see android.widget.TabHost#getCurrentTabTag()
     */
    public String getCurrentTabTag()
    {
        if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size())
        {
            return mTabSpecs.get(mCurrentTab).getTag();
        }
        return null;
    }

    /**
     * 
     * getCurrentTabView
     * 
     * @return View
     * @see android.widget.TabHost#getCurrentTabView()
     */
    public View getCurrentTabView()
    {
        if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size())
        {
            return mTabWidget.getChildAt(mCurrentTab);
        }
        return null;
    }

    public View getCurrentView()
    {
        return mCurrentView;
    }

    /**
     * 
     * setCurrentTabByTag
     * 
     * @param tag aa
     * @see android.widget.TabHost#setCurrentTabByTag(java.lang.String)
     */
    public void setCurrentTabByTag(String tag)
    {
        int i;
        for (i = 0; i < mTabSpecs.size(); i++)
        {
            if (mTabSpecs.get(i).getTag().equals(tag))
            {
                setCurrentTab(i);
                break;
            }
        }
    }

    /**
     * 
     * getTabContentView
     * 
     * @return FrameLayout
     * @see android.widget.TabHost#getTabContentView()
     */
    public FrameLayout getTabContentView()
    {
        return mTabContent;
    }

    /**
     * 
     * dispatchKeyEvent
     * 
     * @param event KeyEvent
     * @return boolean
     * @see android.widget.TabHost#dispatchKeyEvent(android.view.KeyEvent)
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event)
    {
        boolean handled = false;
        try
        {
            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.hasFocus())
                && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null))
            {
                mTabWidget.getChildAt(mCurrentTab).requestFocus();
                playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
                return true;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            // Log.w("not focuse",
            // e.getMessage());
        }
        return handled;
    }

    /**
     * 
     * dispatchWindowFocusChanged
     * 
     * @param hasFocus boolean
     * @see android.widget.TabHost#dispatchWindowFocusChanged(boolean)
     */
    @Override
    public void dispatchWindowFocusChanged(boolean hasFocus)
    {
        mCurrentView.dispatchWindowFocusChanged(hasFocus);
    }

    /**
     * 
     * setCurrentTab
     * 
     * @param index int
     * @see android.widget.TabHost#setCurrentTab(int)
     */
    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 MyTabHost.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
    {
        /**
         * onTabChanged
         * 
         * @param tabId String
         */
        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;
        }

        /**
         * 
         * setIndicator
         * 
         * @param label CharSequence
         * @return TabSpec
         */
        public TabSpec setIndicator(CharSequence label)
        {
            mIndicatorStrategy = new LabelIndicatorStrategy(label);
            return this;
        }

        /**
         * 
         * setIndicator
         * 
         * @param label CharSequence
         * @param icon Drawable
         * @return TabSpec
         */
        public TabSpec setIndicator(CharSequence label, Drawable icon)
        {
            mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon);
            return this;
        }

        /**
         * setContent
         * 
         * @param viewId int
         * @return TabSpec
         */
        public TabSpec setContent(int viewId)
        {
            mContentStrategy = new ViewIdContentStrategy(viewId);
            return this;
        }

        /**
         * setContent
         * 
         * @param contentFactory TabContentFactory
         * @return TabSpec
         */
        public TabSpec setContent(TabContentFactory contentFactory)
        {
            mContentStrategy = new FactoryContentStrategy(mTag, contentFactory);
            return this;
        }

        /**
         * setContent
         * 
         * @param intent Intent
         * @return TabSpec
         */
        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);
            int tabInd = isParent ? R.layout.tab_indicator
                : R.layout.tab_indicator_child;
            View tabIndicator = inflater.inflate(tabInd, mTabWidget, // tab widget is the parent
                false); // no inflate params
            if (isParent)
            {
                tabIndicator.setBackgroundResource(R.drawable.tab_indicator);
            }
            else
            {
                tabIndicator.setBackgroundResource(R.drawable.tab_indicator);
            }

            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

            tabIndicator.setBackgroundResource(R.drawable.tab_indicator);

            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);
            }
        }
    }

    /**
     * 设置是否是父tab
     * 
     * @param isP boolean
     */
    public void setIsParent(boolean isP)
    {
        isParent = isP;
    }

 

 Widget:

 

public class MyTabWidget extends LinearLayout implements OnFocusChangeListener
{

    private OnTabSelectionChanged mSelectionChangedListener;
    private int mSelectedTab = 0;

    /**
     * 
     * @param context Context
     */
    public MyTabWidget(Context context)
    {
        this(context, null);
    }

    /**
     * 
     * @param context Context
     * @param attrs AttributeSet
     */
    public MyTabWidget(Context context, AttributeSet attrs)
    {
        this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
    }

    /**
     * 
     * @param context Context
     * @param attrs AttributeSet
     * @param defStyle int
     */
    public MyTabWidget(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs);
        initTabWidget();

        TypedArray a = context.obtainStyledAttributes(attrs,
            com.android.internal.R.styleable.TabWidget, defStyle, 0);

        a.recycle();
    }

    /**
     * 
     * 
     * 
     * @param w int
     * @param h int
     * @param oldw int
     * @param oldh int
     * @see android.view.View#onSizeChanged(int, int, int, int)
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    private void initTabWidget()
    {
        setOrientation(LinearLayout.HORIZONTAL);
        // mBottomLeftStrip = mContext
        // .getResources()
        // .getDrawable(com.android.internal.R.drawable.tab_bottom_left);
        // mBottomRightStrip = mContext
        // .getResources()
        // .getDrawable(com.android.internal.R.drawable.tab_bottom_right);
        // Deal with focus, as we don't want the focus to go by default
        // to a tab other than the current tab
        setFocusable(true);
        setOnFocusChangeListener(this);
    }

    /**
     * 
     * 
     * 
     * @param child View
     * @see android.view.ViewGroup#childDrawableStateChanged(android.view.View)
     */
    @Override
    public void childDrawableStateChanged(View child)
    {
        if (child == getChildAt(mSelectedTab))
        {
            // To make sure that the bottom strip is redrawn
            invalidate();
        }
        super.childDrawableStateChanged(child);
    }

    /**
     * 
     * 屏蔽了底下的线
     * 
     * @param canvas Canvas
     * @see android.view.ViewGroup#dispatchDraw(android.graphics.Canvas)
     */
    @Override
    public void dispatchDraw(Canvas canvas)
    {
        super.dispatchDraw(canvas);

    }

    /**
     * Sets the current tab. This method is used to bring a tab to the front of
     * the Widget, and is used to post to the rest of the UI that a different
     * tab has been brought to the foreground.
     * 
     * Note, this is separate from the traditional "focus" that is employed from
     * the view logic.
     * 
     * For instance, if we have a list in a tabbed view, a user may be
     * navigating up and down the list, moving the UI focus (orange
     * highlighting) through the list items. The cursor movement does not effect
     * the "selected" tab though, because what is being scrolled through is all
     * on the same tab. The selected tab only changes when we navigate between
     * tabs (moving from the list view to the next tabbed view, in this
     * example).
     * 
     * To move both the focus AND the selected tab at once, please use
     * {@link #setCurrentTab}. Normally, the view logic takes care of adjusting
     * the focus, so unless you're circumventing the UI, you'll probably just
     * focus your interest here.
     * 
     * @param index The tab that you want to indicate as the selected tab (tab
     *            brought to the front of the widget)
     * 
     * @see #focusCurrentTab
     */
    public void setCurrentTab(int index)
    {
        if (index < 0 || index >= getChildCount())
        {
            return;
        }

        getChildAt(mSelectedTab).setSelected(false);
        mSelectedTab = index;
        getChildAt(mSelectedTab).setSelected(true);
    }

    /**
     * Sets the current tab and focuses the UI on it. This method makes sure
     * that the focused tab matches the selected tab, normally at
     * {@link #setCurrentTab}. Normally this would not be an issue if we go
     * through the UI, since the UI is responsible for calling
     * TabWidget.onFocusChanged(), but in the case where we are selecting the
     * tab programmatically, we'll need to make sure focus keeps up.
     * 
     * @param index The tab that you want focused (highlighted in orange) and
     *            selected (tab brought to the front of the widget)
     * 
     * @see #setCurrentTab
     */
    public void focusCurrentTab(int index)
    {
        final int oldTab = mSelectedTab;

        // set the tab
        setCurrentTab(index);

        // change the focus if applicable.
        if (oldTab != index)
        {
            getChildAt(index).requestFocus();
        }
    }

    /**
     * 
     * 
     * 
     * @param enabled boolean
     * @see android.view.View#setEnabled(boolean)
     */
    @Override
    public void setEnabled(boolean enabled)
    {
        super.setEnabled(enabled);
        int count = getChildCount();

        for (int i = 0; i < count; i++)
        {
            View child = getChildAt(i);
            child.setEnabled(enabled);
        }
    }

    /**
     * 
     * 
     * 
     * @param child View
     * @see android.view.ViewGroup#addView(android.view.View)
     */
    @Override
    public void addView(View child)
    {
        if (child.getLayoutParams() == null)
        {
            final LinearLayout.LayoutParams lp = new LayoutParams(0,
                ViewGroup.LayoutParams.WRAP_CONTENT, 1);
            lp.setMargins(0, 0, 0, 0);
            child.setLayoutParams(lp);
        }

        // Ensure you can navigate to the tab with the keyboard, and you can
        // touch it
        child.setFocusable(true);
        child.setClickable(true);

        super.addView(child);

        // than potentially interfere with the view's listener
        child.setOnClickListener(new TabClickListener(getChildCount() - 1));
        child.setOnFocusChangeListener(this);
    }

    /**
     * Provides a way for {@link TabHost} to be notified that the user clicked
     * on a tab indicator.
     */
    void setTabSelectionListener(OnTabSelectionChanged listener)
    {
        mSelectionChangedListener = listener;
    }

    /**
     * 
     * 
     * 
     * @param v View
     * @param hasFocus boolean
     * @see android.view.View.OnFocusChangeListener#onFocusChange(android.view.View,
     *      boolean)
     */
    public void onFocusChange(View v, boolean hasFocus)
    {
        if (v == this && hasFocus)
        {
            getChildAt(mSelectedTab).requestFocus();
            return;
        }

        if (hasFocus)
        {
            int i = 0;
            while (i < getChildCount())
            {
                if (getChildAt(i) == v)
                {
                    setCurrentTab(i);
                    mSelectionChangedListener.onTabSelectionChanged(i, false);
                    break;
                }
                i++;
            }
        }
    }

    // registered with each tab indicator so we can notify tab host
    /**
     * 
     * TabClickListener
     * 
     * @version [MTVClient_Handset_R001C08L0ZT05, 2010-10-23]
     */
    private class TabClickListener implements OnClickListener
    {

        private final int mTabIndex;

        private TabClickListener(int tabIndex)
        {
            mTabIndex = tabIndex;
        }

        public void onClick(View v)
        {
            mSelectionChangedListener.onTabSelectionChanged(mTabIndex, true);
        }
    }

    /**
     * Let {@link TabHost} know that the user clicked on a tab indicator.
     */
    static interface OnTabSelectionChanged
    {
        /**
         * Informs the TabHost which tab was selected. It also indicates if the
         * tab was clicked/pressed or just focused into.
         * 
         * @param tabIndex index of the tab that was selected
         * @param clicked whether the selection changed due to a touch/click or
         *            due to focus entering the tab through navigation. Pass
         *            true if it was due to a press/click and false otherwise.
         */
        void onTabSelectionChanged(int tabIndex, boolean clicked);
    }

}

 

tab xml

 

<?xml version="1.0" encoding="utf-8"?>
<com.sleightdemos.widget.MyTabHost
	xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabhost"
	android:layout_width="fill_parent" android:layout_height="fill_parent">
	<TextView android:id="@+id/title" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:footerDividersEnabled="true"
		android:headerDividersEnabled="true" android:textSize="@dimen/title"
		android:gravity="center" android:background="@drawable/titlebar"
		android:textColor="@color/white" />
	<LinearLayout android:orientation="vertical"
		android:layout_width="fill_parent" android:layout_height="fill_parent">
		<com.sleightdemos.widget.MyTabWidget
			android:id="@+id/tabs" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:paddingTop="31dip" />
		<FrameLayout android:id="@+id/tabcontent"
			android:layout_width="fill_parent" android:layout_height="0dip"
			android:layout_weight="1" />
	</LinearLayout>
</com.sleightdemos.widget.MyTabHost>
 

 

 tab_content xml

 

<?xml version="1.0" encoding="utf-8"?>
<com.sleightdemos.widget.MyTabHost
	xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabhost"
	android:layout_width="fill_parent" android:layout_height="fill_parent">
	<LinearLayout android:orientation="vertical"
		android:layout_width="fill_parent" android:layout_height="fill_parent">
		<com.sleightdemos.widget.MyTabWidget
			android:id="@+id/tabs" android:layout_width="fill_parent"
			android:layout_height="wrap_content" />
		<FrameLayout android:id="@+id/tabcontent"
			android:layout_width="fill_parent" android:layout_height="0dip"
			android:layout_weight="1" />
	</LinearLayout>
</com.sleightdemos.widget.MyTabHost>

 

 

tab_indicator xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="0dip" android:layout_height="64dip"
	android:layout_weight="1" android:orientation="vertical">
	<ImageView android:id="@+id/icon" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_centerHorizontal="true" />
	<TextView android:id="@+id/title" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_alignParentBottom="true"
		android:layout_centerHorizontal="true" android:textColor="@color/white"
		android:singleLine="true" android:ellipsize="marquee" />
</RelativeLayout>

 

tab_inicator_child xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="0dip" android:layout_height="64dip"
	android:layout_weight="1" android:orientation="vertical">
	<TextView android:id="@+id/title" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_centerVertical="true"
		android:layout_centerHorizontal="true" android:textColor="@color/white"
		android:singleLine="true" android:ellipsize="marquee" android:text="" />
</RelativeLayout>
 

values/dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<dimen name="title">20sp</dimen>
</resources>
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值