修改动态tab页
1.继承HorizontalScrollView类
2.代码添加tab项
3.计算tab项的宽度,调用子类的onMeasure修改宽度
4.通过OverScroller实现tab项居中效果
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2011 Jake Wharton
*
* 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.
*/
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import com.future.wodownloadmanager.R;
import com.future.wodownloadmanager.entity.CategoryEntity;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class TabIndicator extends HorizontalScrollView {
private Runnable mTabSelector;
private RadioGroup mTabLayout;
private int mMaxTabWidth;
private int mSelectedTabIndex = 1;
private OnTabSelectedListener mTabSelectedListener;
private int childCount;
private String tabString;
private Resources mResources;
public interface OnTabSelectedListener {
/**
* Callback when the selected tab has been reselected.
*
* @param position
* Position of the current center item.
*/
void onTabSelected(int position, String id, String name);
}
private final OnClickListener mTabClickListener = new OnClickListener() {
public void onClick(View view) {
TabView tabView = (TabView) view;
setTabString(tabView.getText().toString());
final int newSelected = tabView.getIndex();
if (newSelected != mSelectedTabIndex) {
mSelectedTabIndex = newSelected;
// animateToTab(mSelectedTabIndex - 1);
animateToTab(tabView);
if (mTabSelectedListener != null) {
mTabSelectedListener.onTabSelected(mSelectedTabIndex,
tabView.getmId(), tabView.getmName());
}
}
}
};
public TabIndicator(Context context) {
super(context);
init(context);
}
public TabIndicator(Context context, Resources resources) {
super(context);
mResources = resources;
init(context);
}
public void setOnTabSelectedListener(OnTabSelectedListener listener) {
mTabSelectedListener = listener;
}
private void init(Context context) {
setHorizontalScrollBarEnabled(false);
mTabLayout = new RadioGroup(context);
mTabLayout.setOrientation(RadioGroup.HORIZONTAL);
addView(mTabLayout, new ViewGroup.LayoutParams(WRAP_CONTENT,
MATCH_PARENT));
}
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
mTabLayout.setOnCheckedChangeListener(listener);
}
public TabIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
setFillViewport(lockedExpanded);
final int childCount = this.childCount;// mTabLayout.getChildCount();
if (childCount > 1
&& (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
int screenWidth = MeasureSpec.getSize(widthMeasureSpec);
// 去除中间分割线宽度
screenWidth = screenWidth - (childCount - 1) * 2;
if (childCount > 4) {
mMaxTabWidth = (int) (screenWidth * 0.3f);
} else {
mMaxTabWidth = screenWidth / childCount;
}
} else {
mMaxTabWidth = -1;
}
// 最后调用onMeasure方法
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void animateToTab(final View tabView) {
if (tabView == null) {
return;
}
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft()
- (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
private void animateToTab(final int position) {
final View tabView = mTabLayout.getChildAt(position);
if (tabView == null) {
return;
}
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft()
- (getWidth() - tabView.getWidth()) / 2;
// DebugLog.v("TabIndicator",
// "animateToTab.position=" + position + ", tabView="
// + tabView + ", Left=" + tabView.getLeft()
// + ", width=" + tabView.getWidth()
// + ", getWidth()=" + getWidth() + ", scrollPos="
// + scrollPos);
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
post(mTabSelector);
}
}
public void setTab(ArrayList<CategoryEntity> tabs) {
if (tabs != null) {
mTabLayout.removeAllViews();
mTabLayout.clearCheck();
int index = 1;
String id = "";
String name = "";
int size = tabs.size();
childCount = size;
for (CategoryEntity entity : tabs) {
if (index == 1) {
id = entity.getId();
name = entity.getName();
}
addTab(index, entity.getId(), entity.getName(), size == index);
index++;
}
if (size > 0) {
setTabString(name);
mSelectedTabIndex = 1;
mTabLayout.check(1);
animateToTab(0);
if (mTabSelectedListener != null) {
mTabSelectedListener.onTabSelected(mSelectedTabIndex, id,
name);
}
}
requestLayout();
}
}
public String getTabString() {
return tabString;
}
public void setTabString(String tabString) {
this.tabString = tabString;
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}
private void addTab(int index, String id, String text, boolean isLast) {
final TabView tabView = new TabView(getContext());
tabView.mIndex = index;
tabView.mId = id;
tabView.mName = text;
tabView.setId(index);
tabView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
tabView.setPadding(0, 18, 0, 18);
tabView.setBackgroundColor(Color.WHITE);
// tabView.setBackgroundResource(R.drawable.selector_tab);
// tabView.setTextAppearance(this.getContext(), R.style.FreeTabStyle);
tabView.setTextColor(mResources
.getColorStateList(R.drawable.color_tab_text));
tabView.setTextSize(16);
/**
* <item name="android:textColor">@drawable/color_tab_text</item> <item
* name="android:textSize">16sp</item> <item
* name="android:textStyle">normal</item>
*/
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
tabView.setText(text);
mTabLayout.addView(tabView, new RadioGroup.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1));
// 添加分割线
// if (!isLast) {
// View line = new View(getContext());
// line.setBackgroundResource(R.drawable.shadow_line);
// line.setLayoutParams(new RadioGroup.LayoutParams(2,
// LayoutParams.MATCH_PARENT));
// mTabLayout.addView(line);
// }
}
private class TabView extends RadioButton {
private int mIndex;
private String mId;
private String mName;
public TabView(Context context) {
super(context);
this.setButtonDrawable(android.R.color.transparent);
}
public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setButtonDrawable(android.R.color.transparent);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mMaxTabWidth > 0 && getMeasuredWidth() < mMaxTabWidth) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxTabWidth,
MeasureSpec.EXACTLY), heightMeasureSpec);
}
}
public int getIndex() {
return mIndex;
}
public String getmId() {
return mId;
}
public String getmName() {
return mName;
}
}
}