Merge change 2900 into donut
* changes: Add support for custom tab views in TabHost and TabWidget.
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
for (int i = 0; i < count; 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;
|
||||
|
||||
Reference in New Issue
Block a user