Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b4b50b8 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 2900 into donut

* changes:
  Add support for custom tab views in TabHost and TabWidget.
parents 218ebf12 53175148
Loading
Loading
Loading
Loading
+75 −1
Original line number Diff line number Diff line
@@ -46362,7 +46362,7 @@
</parameter>
<parameter name="height" type="int">
</parameter>
<parameter name="edge" type="int">
<parameter name="inset" type="int">
</parameter>
<parameter name="color" type="int">
</parameter>
@@ -173571,6 +173571,17 @@
 deprecated="not deprecated"
 visibility="public"
>
<method name="getTag"
 return="java.lang.String"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="setContent"
 return="android.widget.TabHost.TabSpec"
 abstract="false"
@@ -173638,6 +173649,19 @@
<parameter name="icon" type="android.graphics.drawable.Drawable">
</parameter>
</method>
<method name="setIndicator"
 return="android.widget.TabHost.TabSpec"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="view" type="android.view.View">
</parameter>
</method>
</class>
<class name="TabWidget"
 extends="android.widget.LinearLayout"
@@ -173711,6 +173735,30 @@
<parameter name="index" type="int">
</parameter>
</method>
<method name="getChildTabViewAt"
 return="android.view.View"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="index" type="int">
</parameter>
</method>
<method name="getTabCount"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="onFocusChange"
 return="void"
 abstract="false"
@@ -173739,6 +173787,32 @@
<parameter name="index" type="int">
</parameter>
</method>
<method name="setDividerDrawable"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="drawable" type="android.graphics.drawable.Drawable">
</parameter>
</method>
<method name="setDividerDrawable"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="resId" type="int">
</parameter>
</method>
</class>
<class name="TableLayout"
 extends="android.widget.LinearLayout"
+34 −4
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
            // 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();
                mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
            }
        }
    }
@@ -197,6 +197,12 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
        }
        View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView();
        tabIndicator.setOnKeyListener(mTabKeyListener);

        // If this is a custom view, then do not draw the bottom strips for
        // the tab indicators.
        if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) {
            mTabWidget.setDrawBottomStrips(false);
        }
        mTabWidget.addView(tabIndicator);
        mTabSpecs.add(tabSpec);

@@ -235,7 +241,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");

    public View getCurrentTabView() {
        if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
            return mTabWidget.getChildAt(mCurrentTab);
            return mTabWidget.getChildTabViewAt(mCurrentTab);
        }
        return null;
    }
@@ -273,7 +279,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
                && (mCurrentView.isRootNamespace())
                && (mCurrentView.hasFocus())
                && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
            mTabWidget.getChildAt(mCurrentTab).requestFocus();
            mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
            playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
            return true;
        }
@@ -410,6 +416,14 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
            return this;
        }

        /**
         * Specify a view as the tab indicator.
         */
        public TabSpec setIndicator(View view) {
            mIndicatorStrategy = new ViewIndicatorStrategy(view);
            return this;
        }

        /**
         * Specify the id of the view that should be used as the content
         * of the tab.
@@ -437,7 +451,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
        }


        String getTag() {
        public String getTag() {
            return mTag;
        }
    }
@@ -525,6 +539,22 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
        }
    }

    /**
     * How to create a tab indicator by specifying a view.
     */
    private class ViewIndicatorStrategy implements IndicatorStrategy {

        private final View mView;

        private ViewIndicatorStrategy(View view) {
            mView = view;
        }

        public View createIndicatorView() {
            return mView;
        }
    }

    /**
     * How to create the tab content via a view id.
     */
+94 −16
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
    private Drawable mBottomLeftStrip;
    private Drawable mBottomRightStrip;
    private boolean mStripMoved;
    private Drawable mDividerDrawable;
    private boolean mDrawBottomStrips = true;

    public TabWidget(Context context) {
        this(context, null);
@@ -87,9 +89,68 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
        setOnFocusChangeListener(this);
    }

    /**
     * Returns the tab indicator view at the given index.
     *
     * @param index the zero-based index of the tab indicator view to return
     * @return the tab indicator view at the given index
     */
    public View getChildTabViewAt(int index) {
        // If we are using dividers, then instead of tab views at 0, 1, 2, ...
        // we have tab views at 0, 2, 4, ...
        if (mDividerDrawable != null) {
            index *= 2;
        }
        return getChildAt(index);
    }

    /**
     * Returns the number of tab indicator views.
     * @return the number of tab indicator views.
     */
    public int getTabCount() {
        int children = getChildCount();

        // If we have dividers, then we will always have an odd number of
        // children: 1, 3, 5, ... and we want to convert that sequence to
        // this: 1, 2, 3, ...
        if (mDividerDrawable != null) {
            children = (children + 1) / 2;
        }
        return children;
    }

    /**
     * Sets the drawable to use as a divider between the tab indicators.
     * @param drawable the divider drawable
     */
    public void setDividerDrawable(Drawable drawable) {
        mDividerDrawable = drawable;
    }

    /**
     * Sets the drawable to use as a divider between the tab indicators.
     * @param resId the resource identifier of the drawable to use as a
     * divider.
     */
    public void setDividerDrawable(int resId) {
        mDividerDrawable = mContext.getResources().getDrawable(resId);
    }

    /**
     * Controls whether the bottom strips on the tab indicators are drawn or
     * not.  The default is to draw them.  If the user specifies a custom
     * view for the tab indicators, then the TabHost class calls this method
     * to disable drawing of the bottom strips.
     * @param drawBottomStrips true if the bottom strips should be drawn.
     */
    void setDrawBottomStrips(boolean drawBottomStrips) {
        mDrawBottomStrips = drawBottomStrips;
    }

    @Override
    public void childDrawableStateChanged(View child) {
        if (child == getChildAt(mSelectedTab)) {
        if (child == getChildTabViewAt(mSelectedTab)) {
            // To make sure that the bottom strip is redrawn
            invalidate();
        }
@@ -100,7 +161,14 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        View selectedChild = getChildAt(mSelectedTab);
        // If the user specified a custom view for the tab indicators, then
        // do not draw the bottom strips.
        if (!mDrawBottomStrips) {
            // Skip drawing the bottom strips.
            return;
        }

        View selectedChild = getChildTabViewAt(mSelectedTab);
        
        mBottomLeftStrip.setState(selectedChild.getDrawableState());
        mBottomRightStrip.setState(selectedChild.getDrawableState());
@@ -157,13 +225,13 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
     *  @see #focusCurrentTab
     */
    public void setCurrentTab(int index) {
        if (index < 0 || index >= getChildCount()) {
        if (index < 0 || index >= getTabCount()) {
            return;
        }

        getChildAt(mSelectedTab).setSelected(false);
        getChildTabViewAt(mSelectedTab).setSelected(false);
        mSelectedTab = index;
        getChildAt(mSelectedTab).setSelected(true);
        getChildTabViewAt(mSelectedTab).setSelected(true);
        mStripMoved = true;
    }
    
@@ -189,17 +257,17 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
        
        // change the focus if applicable.
        if (oldTab != index) {
            getChildAt(index).requestFocus();
            getChildTabViewAt(index).requestFocus();
        }
    }
    
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        int count = getChildCount();
        int count = getTabCount();
        
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            View child = getChildTabViewAt(i);
            child.setEnabled(enabled);
        }
    }
@@ -218,17 +286,26 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
        child.setFocusable(true);
        child.setClickable(true);

        // If we have dividers between the tabs and we already have at least one
        // tab, then add a divider before adding the next tab.
        if (mDividerDrawable != null && getTabCount() > 0) {
            View divider = new View(mContext);
            final LinearLayout.LayoutParams lp = new LayoutParams(
                    mDividerDrawable.getIntrinsicWidth(),
                    mDividerDrawable.getIntrinsicHeight());
            lp.setMargins(0, 0, 0, 0);
            divider.setLayoutParams(lp);
            divider.setBackgroundDrawable(mDividerDrawable);
            super.addView(divider);
        }
        super.addView(child);

        // TODO: detect this via geometry with a tabwidget listener rather
        // than potentially interfere with the view's listener
        child.setOnClickListener(new TabClickListener(getChildCount() - 1));
        child.setOnClickListener(new TabClickListener(getTabCount() - 1));
        child.setOnFocusChangeListener(this);
    }




    /**
     * Provides a way for {@link TabHost} to be notified that the user clicked on a tab indicator.
     */
@@ -238,14 +315,15 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {

    public void onFocusChange(View v, boolean hasFocus) {
        if (v == this && hasFocus) {
            getChildAt(mSelectedTab).requestFocus();
            getChildTabViewAt(mSelectedTab).requestFocus();
            return;
        }
        
        if (hasFocus) {
            int i = 0;
            while (i < getChildCount()) {
                if (getChildAt(i) == v) {
            int numTabs = getTabCount();
            while (i < numTabs) {
                if (getChildTabViewAt(i) == v) {
                    setCurrentTab(i);
                    mSelectionChangedListener.onTabSelectionChanged(i, false);
                    break;