修改动态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; } } }