Android之把eoe客户端的关联ViewPager的滑动条勾出来使用

使用代码:
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
void setViewPager(ViewPager view); /**
* Bind the indicator to a ViewPager.
*
* @param view
* @param initialPosition
*/
void setViewPager(ViewPager view, int initialPosition); /**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* @param item
*/
void setCurrentItem(int item); /**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener); /**
* Notify the indicator that the fragment list has changed.
*/
void notifyDataSetChanged();
}
TitlePageIndicator 具体重写代码:
TitlePageIndicator extends View implements PageIndicator {
/**
* Percentage indicating what percentage of the screen width away from
* center should the underline be fully faded. A value of 0.25 means that
* halfway between the center of the screen and an edge.
*/
private static final float SELECTION_FADE_PERCENTAGE = 0.25f;
/**
* Percentage indicating what percentage of the screen width away from
* center should the selected text bold turn off. A value of 0.05 means
* that 10% between the center and an edge.
*/
private static final float BOLD_FADE_PERCENTAGE = 0.05f;
/**
* Title text used when no title is provided by the adapter.
*/
private static final String EMPTY_TITLE = "";
/**
* Interface for a callback when the center item has been clicked.
*/
public interface OnCenterItemClickListener {
/**
* Callback when the center item has been clicked.
*
* @param position Position of the current center item.
*/
void onCenterItemClick(int position);
}
public enum IndicatorStyle {
None(0), Triangle(1), Underline(2);
public final int value;
private IndicatorStyle(int value) {
this.value = value;
}
public static IndicatorStyle fromValue(int value) {
for (IndicatorStyle style : IndicatorStyle.values()) {
if (style.value == value) {
return style;
}
}
return null;
}
}
public enum LinePosition {
Bottom(0), Top(1);
public final int value;
private LinePosition(int value) {
this.value = value;
}
public static LinePosition fromValue(int value) {
for (LinePosition position : LinePosition.values()) {
if (position.value == value) {
return position;
}
}
return null;
}
}
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage = -1;
private float mPageOffset;
private int mScrollState;
private final Paint mPaintText = new Paint();
private boolean mBoldText;
private int mColorText;
private int mColorSelected;
private Path mPath = new Path();
private final Rect mBounds = new Rect();
private final Paint mPaintFooterLine = new Paint();
private IndicatorStyle mFooterIndicatorStyle;
private LinePosition mLinePosition;
private final Paint mPaintFooterIndicator = new Paint();
private float mFooterIndicatorHeight;
private float mFooterIndicatorUnderlinePadding;
private float mFooterPadding;
private float mTitlePadding;
private float mTopPadding;
/** Left and right side padding for not active view titles. */
private float mClipPadding;
private float mFooterLineHeight;
private static final int INVALID_POINTER = -1;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
//�Լ�д�� �������Ҿ���
private int TextMaginLeftAndRight=50;
private OnCenterItemClickListener mCenterItemClickListener;
public TitlePageIndicator(Context context) {
this(context, null);
}
public TitlePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiTitlePageIndicatorStyle);
}
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultFooterColor = res.getColor(R.color.default_title_indicator_footer_color);
final float defaultFooterLineHeight = res.getDimension(R.dimen.default_title_indicator_footer_line_height);
final int defaultFooterIndicatorStyle = res.getInteger(R.integer.default_title_indicator_footer_indicator_style);
final float defaultFooterIndicatorHeight = res.getDimension(R.dimen.default_title_indicator_footer_indicator_height);
final float defaultFooterIndicatorUnderlinePadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_underline_padding);
final float defaultFooterPadding = res.getDimension(R.dimen.default_title_indicator_footer_padding);
final int defaultLinePosition = res.getInteger(R.integer.default_title_indicator_line_position);
final int defaultSelectedColor = res.getColor(R.color.default_title_indicator_selected_color);
final boolean defaultSelectedBold = res.getBoolean(R.bool.default_title_indicator_selected_bold);
final int defaultTextColor = res.getColor(R.color.default_title_indicator_text_color);
final float defaultTextSize = res.getDimension(R.dimen.default_title_indicator_text_size);
final float defaultTitlePadding = res.getDimension(R.dimen.default_title_indicator_title_padding);
final float defaultClipPadding = res.getDimension(R.dimen.default_title_indicator_clip_padding);
final float defaultTopPadding = res.getDimension(R.dimen.default_title_indicator_top_padding);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, 0);
//Retrieve the colors to be used for this view and apply them.
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
mFooterIndicatorStyle = IndicatorStyle.fromValue(a.getInteger(R.styleable.TitlePageIndicator_footerIndicatorStyle, defaultFooterIndicatorStyle));
mFooterIndicatorHeight = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorHeight, defaultFooterIndicatorHeight);
mFooterIndicatorUnderlinePadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorUnderlinePadding, defaultFooterIndicatorUnderlinePadding);
mFooterPadding = a.getDimension(R.styleable.TitlePageIndicator_footerPadding, defaultFooterPadding);
mLinePosition = LinePosition.fromValue(a.getInteger(R.styleable.TitlePageIndicator_linePosition, defaultLinePosition));
mTopPadding = a.getDimension(R.styleable.TitlePageIndicator_topPadding, defaultTopPadding);
mTitlePadding = a.getDimension(R.styleable.TitlePageIndicator_titlePadding, defaultTitlePadding);
mClipPadding = a.getDimension(R.styleable.TitlePageIndicator_clipPadding, defaultClipPadding);
mColorSelected = a.getColor(R.styleable.TitlePageIndicator_selectedColor, defaultSelectedColor);
mColorText = a.getColor(R.styleable.TitlePageIndicator_android_textColor, defaultTextColor);
mBoldText = a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold);
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_android_textSize, defaultTextSize);
final int footerColor = a.getColor(R.styleable.TitlePageIndicator_footerColor, defaultFooterColor);
mPaintText.setTextSize(textSize);
mPaintText.setAntiAlias(true);
mPaintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterIndicator.setColor(footerColor);
Drawable background = a.getDrawable(R.styleable.TitlePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public int getFooterColor() {
return mPaintFooterLine.getColor();
}
public void setFooterColor(int footerColor) {
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setColor(footerColor);
invalidate();
}
public float getFooterLineHeight() {
return mFooterLineHeight;
}
public void setFooterLineHeight(float footerLineHeight) {
mFooterLineHeight = footerLineHeight;
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
invalidate();
}
public float getFooterIndicatorHeight() {
return mFooterIndicatorHeight;
}
public void setFooterIndicatorHeight(float footerTriangleHeight) {
mFooterIndicatorHeight = footerTriangleHeight;
invalidate();
}
public float getFooterIndicatorPadding() {
return mFooterPadding;
}
public void setFooterIndicatorPadding(float footerIndicatorPadding) {
mFooterPadding = footerIndicatorPadding;
invalidate();
}
public IndicatorStyle getFooterIndicatorStyle() {
return mFooterIndicatorStyle;
}
public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
mFooterIndicatorStyle = indicatorStyle;
invalidate();
}
public LinePosition getLinePosition() {
return mLinePosition;
}
public void setLinePosition(LinePosition linePosition) {
mLinePosition = linePosition;
invalidate();
}
public int getSelectedColor() {
return mColorSelected;
}
public void setSelectedColor(int selectedColor) {
mColorSelected = selectedColor;
invalidate();
}
public boolean isSelectedBold() {
return mBoldText;
}
public void setSelectedBold(boolean selectedBold) {
mBoldText = selectedBold;
invalidate();
}
public int getTextColor() {
return mColorText;
}
public void setTextColor(int textColor) {
mPaintText.setColor(textColor);
mColorText = textColor;
invalidate();
}
public float getTextSize() {
return mPaintText.getTextSize();
}
public void setTextSize(float textSize) {
mPaintText.setTextSize(textSize);
invalidate();
}
public float getTitlePadding() {
return this.mTitlePadding;
}
public void setTitlePadding(float titlePadding) {
mTitlePadding = titlePadding;
invalidate();
}
public float getTopPadding() {
return this.mTopPadding;
}
public void setTopPadding(float topPadding) {
mTopPadding = topPadding;
invalidate();
}
public float getClipPadding() {
return this.mClipPadding;
}
public void setClipPadding(float clipPadding) {
mClipPadding = clipPadding;
invalidate();
}
public void setTypeface(Typeface typeface) {
mPaintText.setTypeface(typeface);
invalidate();
}
public Typeface getTypeface() {
return mPaintText.getTypeface();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
// mCurrentPage is -1 on first start and after orientation changed. If so, retrieve the correct index from viewpager.
if (mCurrentPage == -1 && mViewPager != null) {
mCurrentPage = mViewPager.getCurrentItem();
}
//Calculate views bounds
ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
final int boundsSize = bounds.size();
//Make sure we're on a page that still exists
if (mCurrentPage >= boundsSize) {
setCurrentItem(boundsSize - 1);
return;
}
final int countMinusOne = count - 1;
final float halfWidth = getWidth() / 2f;
final int left = getLeft();
final float leftClip = left + mClipPadding;
final int width = getWidth();
int height = getHeight();
final int right = left + width;
final float rightClip = right - mClipPadding;
int page = mCurrentPage;
float offsetPercent;
if (mPageOffset <= 0.5) {
offsetPercent = mPageOffset;
} else {
page += 1;
offsetPercent = 1 - mPageOffset;
}
final boolean currentSelected = (offsetPercent <= SELECTION_FADE_PERCENTAGE);
final boolean currentBold = (offsetPercent <= BOLD_FADE_PERCENTAGE);
final float selectedPercent = (SELECTION_FADE_PERCENTAGE - offsetPercent) / SELECTION_FADE_PERCENTAGE;
//Verify if the current view must be clipped to the screen
Rect curPageBound = bounds.get(mCurrentPage);
float curPageWidth = curPageBound.right - curPageBound.left;
if (curPageBound.left < leftClip) {
//Try to clip to the screen (left side)
clipViewOnTheLeft(curPageBound, curPageWidth, left);
}
if (curPageBound.right > rightClip) {
//Try to clip to the screen (right side)
clipViewOnTheRight(curPageBound, curPageWidth, right);
}
//Left views starting from the current position
if (mCurrentPage > 0) {
for (int i = mCurrentPage - 1; i >= 0; i--) {
Rect bound = bounds.get(i);
//Is left side is outside the screen
if (bound.left < leftClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (left side)
clipViewOnTheLeft(bound, w, left);
//Except if there's an intersection with the right view
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Right views starting from the current position
if (mCurrentPage < countMinusOne) {
for (int i = mCurrentPage + 1 ; i < count; i++) {
Rect bound = bounds.get(i);
//If right side is outside the screen
if (bound.right > rightClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (right side)
clipViewOnTheRight(bound, w, right);
//Except if there's an intersection with the left view
Rect leftBound = bounds.get(i - 1);
//Intersection
if (bound.left - mTitlePadding < leftBound.right) {
bound.left = (int) (leftBound.right + mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Now draw views
int colorTextAlpha = mColorText >>> 24;
for (int i = 0; i < count; i++) {
//Get the title
Rect bound = bounds.get(i);
//Only if one side is visible
if ((bound.left > left && bound.left < right) || (bound.right > left && bound.right < right)) {
final boolean currentPage = (i == page);
final CharSequence pageTitle = getTitle(i);
//Only set bold if we are within bounds
mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);
//Draw text as unselected
mPaintText.setColor(mColorText);
if(currentPage && currentSelected) {
//Fade out/in unselected text as the selected text fades in/out
mPaintText.setAlpha(colorTextAlpha - (int)(colorTextAlpha * selectedPercent));
}
//Except if there's an intersection with the right view
if (i < boundsSize - 1) {
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
int w = bound.right - bound.left;
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left+TextMaginLeftAndRight/2, bound.bottom + mTopPadding, mPaintText);
//If we are within the selected bounds draw the selected text
if (currentPage && currentSelected) {
mPaintText.setColor(mColorSelected);
mPaintText.setAlpha((int)((mColorSelected >>> 24) * selectedPercent));
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left+TextMaginLeftAndRight/2, bound.bottom + mTopPadding, mPaintText);
}
}
}
//If we want the line on the top change height to zero and invert the line height to trick the drawing code
float footerLineHeight = mFooterLineHeight;
float footerIndicatorLineHeight = mFooterIndicatorHeight;
if (mLinePosition == LinePosition.Top) {
height = 0;
footerLineHeight = -footerLineHeight;
footerIndicatorLineHeight = -footerIndicatorLineHeight;
}
//Draw the footer line
mPath.reset();
mPath.moveTo(0, height - footerLineHeight / 2f);
mPath.lineTo(width, height - footerLineHeight / 2f);
mPath.close();
canvas.drawPath(mPath, mPaintFooterLine);
float heightMinusLine = height - footerLineHeight;
switch (mFooterIndicatorStyle) {
case Triangle:
mPath.reset();
mPath.moveTo(halfWidth, heightMinusLine - footerIndicatorLineHeight);
mPath.lineTo(halfWidth + footerIndicatorLineHeight, heightMinusLine);
mPath.lineTo(halfWidth - footerIndicatorLineHeight, heightMinusLine);
mPath.close();
canvas.drawPath(mPath, mPaintFooterIndicator);
break;
case Underline:
if (!currentSelected || page >= boundsSize) {
break;
}
Rect underlineBounds = bounds.get(page);
final float rightPlusPadding = underlineBounds.right + mFooterIndicatorUnderlinePadding;
final float leftMinusPadding = underlineBounds.left - mFooterIndicatorUnderlinePadding;
final float heightMinusLineMinusIndicator = heightMinusLine - footerIndicatorLineHeight;
mPath.reset();
mPath.moveTo(leftMinusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLineMinusIndicator);
mPath.lineTo(leftMinusPadding, heightMinusLineMinusIndicator);
mPath.close();
mPaintFooterIndicator.setAlpha((int)(0xFF * selectedPercent));
canvas.drawPath(mPath, mPaintFooterIndicator);
mPaintFooterIndicator.setAlpha(0xFF);
break;
}
}
public boolean onTouchEvent(android.view.MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
final float leftThird = halfWidth - sixthWidth;
final float rightThird = halfWidth + sixthWidth;
final float eventX = ev.getX();
if (eventX < leftThird) {
if (mCurrentPage > 0) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
}
} else if (eventX > rightThird) {
if (mCurrentPage < count - 1) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
} else {
//Middle third
if (mCenterItemClickListener != null && action != MotionEvent.ACTION_CANCEL) {
mCenterItemClickListener.onCenterItemClick(mCurrentPage);
}
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
/**
* Set bounds for the right textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheRight(Rect curViewBound, float curViewWidth, int right) {
curViewBound.right = (int) (right - mClipPadding);
curViewBound.left = (int) (curViewBound.right - curViewWidth);
}
/**
* Set bounds for the left textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheLeft(Rect curViewBound, float curViewWidth, int left) {
curViewBound.left = (int) (left + mClipPadding);
curViewBound.right = (int) (mClipPadding + curViewWidth);
}
/**
* Calculate views bounds and scroll them according to the current index
*
* @param paint
* @return
*/
private ArrayList<Rect> calculateAllBounds(Paint paint) {
ArrayList<Rect> list = new ArrayList<Rect>();
//For each views (If no values then add a fake one)
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final int halfWidth = width / 2;
for (int i = 0; i < count; i++) {
Rect bounds = calcBounds(i, paint);
int w = bounds.right - bounds.left;
int h = bounds.bottom - bounds.top;
bounds.left = (int)(halfWidth - (w / 2f) + ((i - mCurrentPage - mPageOffset) * width));
bounds.right = bounds.left + w;
bounds.top = 0;
bounds.bottom = h;
list.add(bounds);
}
return list;
}
/**
* Calculate the bounds for a view's title
*
* @param index
* @param paint
* @return
*/
private Rect calcBounds(int index, Paint paint) {
//Calculate the text bounds
Rect bounds = new Rect();
CharSequence title = getTitle(index);
bounds.right = (int) paint.measureText(title, 0, title.length())+TextMaginLeftAndRight;
bounds.bottom = (int) (paint.descent() - paint.ascent());
return bounds;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
/**
* Set a callback listener for the center item click.
*
* @param listener Callback instance.
*/
public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
mCenterItemClickListener = listener;
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Measure our width in whatever mode specified
final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
//Determine our height
float height;
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightSpecMode == MeasureSpec.EXACTLY) {
//We were told how big to be
height = MeasureSpec.getSize(heightMeasureSpec);
} else {
//Calculate the text bounds
mBounds.setEmpty();
mBounds.bottom = (int) (mPaintText.descent() - mPaintText.ascent());
height = mBounds.bottom - mBounds.top + mFooterLineHeight + mFooterPadding + mTopPadding;
if (mFooterIndicatorStyle != IndicatorStyle.None) {
height += mFooterIndicatorHeight;
}
}
final int measuredHeight = (int)height;
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
private CharSequence getTitle(int i) {
CharSequence title = mViewPager.getAdapter().getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
return title;
}
}
github上面有个开源的也实现勒这个效果:
https://github.com/JakeWharton/Android-ViewPagerIndicator
Android之把eoe客户端的关联ViewPager的滑动条勾出来使用的更多相关文章
- Android中ViewPager实现滑动条及与Fragment结合的实例教程
ViewPager类主要被用来实现可滑动的视图功能,这里我们就来共同学习Android中ViewPager实现滑动条及与Fragment结合的实例教程,需要的朋友可以参考下 自主实现滑动指示条先上一个 ...
- 介绍三个Android支持库控件:TabLayout+ViewPager+RecyclerView
本文主要介绍如下三个Android支持库控件的配合使用: TabLayout:android.support.design.widget.TabLayout ViewPager:android.sup ...
- Android中如何在Eclipse中关联源代码?(图文)
关联源代码 1.删除工程里面的Android Depandencies,删除后会报错,不要理会.看下面 2.添加libs目录下的Android-support-v4.jar包 选中-->右键-- ...
- Android之自定义(上方标题随ViewPager手势慢慢滑动)
最近很蛋疼,项目要模仿网易新闻的样式去做.上次把仿网易新闻客户端的下拉刷新写出来了,这次是ViewPager的滑动,同时ViewPager的上面标题下划线跟随者移动,本来通过ViewPager的OnP ...
- Android Studio2.x版本无法自动关联源码的解决方法
Android Studio2.x版本无法自动关联源码的解决方法 在学习android开发过程中,对于一个不熟悉的类,阅读源码是一个很好的学习方式,使用andorid studio开发工具的SDK M ...
- Android版的菜谱客户端应用源码完整版
Android版的菜谱客户端应用源码完整版,这个文章是从安卓教程网转载过来的,不是本人的原创,希望能够帮到大家的学习吧. <ignore_js_op> 152936qc7jdnv6vo0c ...
- Android 禁止Viewpager左右滑动功能
首先自定义一个 继承自 ViewPager的自定义 类 package com.yourcompany; import android.content.Context; import android. ...
- Android手机SSH Client客户端推荐JuiceSSH
Windows上建立ssh服务器 参见: http://www.cnblogs.com/xred/archive/2012/04/21/2461627.html Android手机SSH Client ...
- Android Studio撤销与SVN的关联
为何会记录这一个问题,主要是在做项目的过程中出现了一个奇怪的现象,就是直接在文件目录下使用svn上传文件的话,可以看到该目录是与SVN相关联的,可是到了用Android Studio上传代码的时候却发 ...
随机推荐
- 一步一步学习IdentityServer3 (3)
在上一篇中配置一个基础的idrserver服务端 这篇文章将对服务端做一些变化,这里我先贴一下上一章中的代码 证书: static class Certificate { public static ...
- 【LOJ】 #2547. 「JSOI2018」防御网络
题解 如果只是一棵树的话,那么就枚举每条边,分成两部分大小为\(a\)和\(b\) 那么这条边被统计的方案数是\((2^a - 1)(2^b - 1)\) 如果是一个环的话,我们枚举环上至少有\(N ...
- 001.RAID简介
一 RAID介绍 独立磁盘冗余数组(RAID, Redundant Array of Independent Disks),旧称廉价磁盘冗余数组(RAID,Redundant Array of Ine ...
- LruCacahe在美团DSP系统中的应用演进
背景 DSP系统是互联网广告需求方平台,用于承接媒体流量,投放广告.业务特点是并发度高,平均响应低(百毫秒). 为了能够有效提高DSP系统的性能,美团平台引入了一种带有清退机制的缓存结构LruCach ...
- 多线程学习笔记六之并发工具类CountDownLatch和CyclicBarrier
目录 简介 CountDownLatch 示例 实现分析 CountDownLatch与Thread.join() CyclicBarrier 实现分析 CountDownLatch和CyclicBa ...
- oracle批量插入優化方案
今天聽DBA説如果從一個表批量查詢出一批數據之後批量插入另外一張表的優化方案: 1)不寫歸檔日誌: 2)採用獨佔 關於insert /*+ append */我們需要注意以下三點: a.非歸檔模式下, ...
- 20172330 2017-2018-1 《Java程序设计》第六周学习总结
学号 2017-2018-2 <程序设计与数据结构>第六周学习总结 教材学习内容总结 这一章主要是对数组的学习: 数组是一种简单而功能强大的编程语言结构,用于分组和组织数据.在java中, ...
- sqlserver -- 查看当前数据库的数据表(备忘)
@_@||... 记性不好,备忘... 语句功能:查看当前数据库的所有表(根据所需,进行语句改写即可) SELECT * FROM sysobjects WHERE (xtype = 'U') 备注: ...
- #pragma pack(n)的使用
在缺省情况下,编译器为了让程序跑得跟快,减少CPU读取数据的指令周期,对结构体的存储进行了优化, 比如:如下结构体 struct s { char ch; int i; }; 虽然变量ch本身只有1个 ...
- mysql导入csv文件
今天尝试将Oracle中的数据导入到mysql中,在SQLyog工具其中看到一些sql语句,拿来记录一下,说不定以后就用的着呐! -----查看ydtf数据库中的基础表,就是用户创建了哪些表 SHOW ...