项目需要一个ViewPager的指示器,发现Android联系人中有该控件,于是抽取出来分享给大家:
ViewPagerTabs .java:
public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
ViewPager mPager;
private ViewPagerTabStrip mTabStrip;
/**
* Linearlayout that will contain the TextViews serving as tabs. This is the only child
* of the parent HorizontalScrollView.
*/
final int mTextStyle;
final ColorStateList mTextColor;
final int mTextSize;
final boolean mTextAllCaps;
int mPrevSelected = -1;
int mSidePadding;
int mUnderlineColor;
int mUnderlineThickness;
private static final int TAB_SIDE_PADDING_IN_DPS = 10;
/**
* Simulates actionbar tab behavior by showing a toast with the tab title when long clicked.
*/
private class OnTabLongClickListener implements OnLongClickListener {
final int mPosition;
public OnTabLongClickListener(int position) {
mPosition = position;
}
@Override
public boolean onLongClick(View v) {
final int[] screenPos = new int[2];
getLocationOnScreen(screenPos);
final Context context = getContext();
final int width = getWidth();
final int height = getHeight();
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition),
Toast.LENGTH_SHORT);
// Show the toast under the tab
toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
(screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height);
toast.show();
return true;
}
}
public ViewPagerTabs(Context context) {
this(context, null);
}
public ViewPagerTabs(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerTabs,defStyle,0);
mTextSize = a.getDimensionPixelSize(R.styleable.ViewPagerTabs_textSize, 0);
mTextStyle = a.getInt(R.styleable.ViewPagerTabs_textStyle, 0);
mTextColor = a.getColorStateList(R.styleable.ViewPagerTabs_textColor);
mTextAllCaps = a.getBoolean(R.styleable.ViewPagerTabs_textAllCap, false);
mUnderlineColor = a.getColor(R.styleable.ViewPagerTabs_underlineColor,0);
mUnderlineThickness = a.getDimensionPixelOffset(R.styleable.ViewPagerTabs_underlineThickness,dp2px(2f));
mTabStrip = new ViewPagerTabStrip(context);
mTabStrip.setUnderlineColor(mUnderlineColor);
mTabStrip.setSelectedUnderlineThickness(mUnderlineThickness);
addView(mTabStrip,
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
a.recycle();
}
public void setViewPager(ViewPager viewPager) {
mPager = viewPager;
addTabs(mPager.getAdapter());
mPager.addOnPageChangeListener(this);
}
private void addTabs(PagerAdapter adapter) {
mTabStrip.removeAllViews();
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
addTab(adapter.getPageTitle(i), i);
}
}
private void addTab(CharSequence tabTitle, final int position) {
final TextView textView = new TextView(getContext());
textView.setText(tabTitle);
textView.setBackgroundResource(R.drawable.view_pager_tab_background);
textView.setGravity(Gravity.CENTER);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPager.setCurrentItem(getRtlPosition(position));
}
});
textView.setOnLongClickListener(new OnTabLongClickListener(position));
// Assign various text appearance related attributes to child views.
if (mTextStyle > 0) {
textView.setTypeface(textView.getTypeface(), mTextStyle);
}
if (mTextSize > 0) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
}
if (mTextColor != null) {
textView.setTextColor(mTextColor);
}
textView.setAllCaps(mTextAllCaps);
textView.setPadding(mSidePadding, 0, mSidePadding, 0);
mTabStrip.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT, 1));
// Default to the first child being selected
if (position == 0) {
mPrevSelected = 0;
textView.setSelected(true);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
position = getRtlPosition(position);
int tabStripChildCount = mTabStrip.getChildCount();
if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
return;
}
mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels);
if(null != onPageChangeListener){
onPageChangeListener.onPageScrolled(position,positionOffset,positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
position = getRtlPosition(position);
if (mPrevSelected >= 0) {
mTabStrip.getChildAt(mPrevSelected).setSelected(false);
}
final View selectedChild = mTabStrip.getChildAt(position);
selectedChild.setSelected(true);
// Update scroll position
final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mPrevSelected = position;
if(null != onPageChangeListener){
onPageChangeListener.onPageSelected(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
if(null != onPageChangeListener){
onPageChangeListener.onPageSelected(state);
}
}
private int getRtlPosition(int position) {
if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
return mTabStrip.getChildCount() - 1 - position;
}
return position;
}
private int dp2px(float dpVal){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getContext().getResources().getDisplayMetrics());
}
private OnPageChangeListener onPageChangeListener;
public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener){
this.onPageChangeListener = onPageChangeListener;
}
public interface OnPageChangeListener{
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
public void onPageSelected(int position);
public void onPageScrollStateChanged(int state);
}
}
ViewPagerTabStrip.java:
public class ViewPagerTabStrip extends LinearLayout {
private int mSelectedUnderlineThickness;
private final Paint mSelectedUnderlinePaint;
private int mIndexForSelection;
private float mSelectionOffset;
private int mUnderlineColor;
private int mBackgroundColor;
public ViewPagerTabStrip(Context context) {
this(context, null);
}
public ViewPagerTabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
final Resources res = context.getResources();
mSelectedUnderlineThickness =
res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
mUnderlineColor = res.getColor(R.color.tab_selected_underline_color);
mBackgroundColor = res.getColor(R.color.actionbar_background_color);
mSelectedUnderlinePaint = new Paint();
mSelectedUnderlinePaint.setColor(mUnderlineColor);
setBackgroundColor(mBackgroundColor);
setWillNotDraw(false);
}
@Override
public void setBackgroundColor(int color) {
super.setBackgroundColor(color);
}
public void setUnderlineColor(int underlineColor){
mUnderlineColor = underlineColor;
mSelectedUnderlinePaint.setColor(mUnderlineColor);
}
public void setSelectedUnderlineThickness(int size){
mSelectedUnderlineThickness = size;
}
/**
* Notifies this view that view pager has been scrolled. We save the tab index
* and selection offset for interpolating the position and width of selection
* underline.
*/
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mIndexForSelection = position;
mSelectionOffset = positionOffset;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
int childCount = getChildCount();
// Thick colored underline below the current selection
if (childCount > 0) {
View selectedTitle = getChildAt(mIndexForSelection);
int selectedLeft = selectedTitle.getLeft();
int selectedRight = selectedTitle.getRight();
final boolean isRtl = isRtl();
final boolean hasNextTab = isRtl ? mIndexForSelection > 0
: (mIndexForSelection < (getChildCount() - 1));
if ((mSelectionOffset > 0.0f) && hasNextTab) {
// Draw the selection partway between the tabs
View nextTitle = getChildAt(mIndexForSelection + (isRtl ? -1 : 1));
int nextLeft = nextTitle.getLeft();
int nextRight = nextTitle.getRight();
selectedLeft = (int) (mSelectionOffset * nextLeft +
(1.0f - mSelectionOffset) * selectedLeft);
selectedRight = (int) (mSelectionOffset * nextRight +
(1.0f - mSelectionOffset) * selectedRight);
}
int height = getHeight();
canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness,
selectedRight, height, mSelectedUnderlinePaint);
}
}
private boolean isRtl() {
return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
使用:
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private String[] title = {"魁拔","秦时明月","海贼王","火影忍者","潮与虎","斩/赤红之瞳","大圣归来"};
private ArrayList<View> views = new ArrayList<View>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i = 0;i < title.length;i++){
TextView textView = new TextView(this);
textView.setGravity(Gravity.CENTER);
textView.setText(title[i]);
views.add(textView);
}
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new TestPageAdapter());
ViewPagerTabs viewPagerTabs = (ViewPagerTabs) findViewById(R.id.tabs);
viewPagerTabs.setViewPager(viewPager);
viewPagerTabs.setOnPageChangeListener(new ViewPagerTabs.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d(TAG,"-onPageScrolled->"+position);
}
@Override
public void onPageSelected(int position) {
Log.d(TAG,"-onPageSelected->"+position);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.d(TAG,"-onPageScrollStateChanged->"+state);
}
});
}
private class TestPageAdapter extends PagerAdapter {
@Override
public int getCount() {
return views.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(views.get(position));
return views.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
}
@Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
}
下载地址:
http://download.csdn.net/detail/lxfeng1098751554/9308233