Android 动态tab

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

	}
}


你可能感兴趣的:(Android 动态tab)