/** * Calculate the bounds for a view's title * * @param index * @param paint * @return */ private RectF calcBounds(int index, Paint paint) { // Calculate the text bounds RectF bounds = new RectF(); bounds.right = paint.measureText(mTitleProvider.getTitle(index)); bounds.bottom = paint.descent() - paint.ascent(); return bounds; }
@Override public void onPageSelected(int position) { setCurrentItem(position); mAdapter.onPageSelected(position); if (mListener != null) { mListener.onPageSelected(position); } }
/** * Returns the title * * @param pos * @return */ private String getTitle(int pos) { // Set the default title String title = "title " + pos; // If the TitleProvider exist if (titleProvider != null) { title = titleProvider.getTitle(pos); } return title; }
@Override public void onClick(View view) { if (!mPagingEnabled) return; final TabView tabView = (TabView) view; if (mCurrentItem == tabView.getIndex()) { mAdapter.onPageReselected(mCurrentItem); } mCurrentItem = tabView.getIndex(); mViewPager.setCurrentItem(mCurrentItem); }
public void notifyDataSetChanged() { if (mTabLayout == null || mViewPager == null) return; mTabLayout.removeAllViews(); mAdapter = (TitleProvider) mViewPager.getAdapter(); if (mAdapter == null) return; final int count = ((PagerAdapter) mAdapter).getCount(); for (int i = 0; i < count; i++) { final String title = mAdapter.getTitle(i); final Drawable icon = mAdapter.getIcon(i); if (title != null && icon != null) { addTab(title, icon, i); } else if (title == null && icon != null) { addTab(icon, i); } else if (title != null && icon == null) { addTab(title, i); } } if (mSelectedTabIndex > count) { mSelectedTabIndex = count - 1; } setCurrentItem(mSelectedTabIndex); requestLayout(); }
/* * (non-Javadoc) * * @see android.view.View#onDraw(android.graphics.Canvas) */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Calculate views bounds ArrayList<RectF> bounds = calculateAllBounds(mPaintText); final int count = mViewPager.getAdapter().getCount(); final int countMinusOne = count - 1; final float halfWidth = getWidth() / 2f; final int left = getLeft(); final float leftClip = left + mClipPadding; final int width = getWidth(); final int height = getHeight(); final int right = left + width; final float rightClip = right - mClipPadding; int page = mCurrentPage; float offsetPercent; if (mCurrentOffset <= halfWidth) { offsetPercent = 1.0f * mCurrentOffset / width; } else { page += 1; offsetPercent = 1.0f * (width - mCurrentOffset) / width; } 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 RectF 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--) { RectF bound = bounds.get(i); // Is left side is outside the screen if (bound.left < leftClip) { float 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 RectF rightBound = bounds.get(i + 1); // Intersection if (bound.right + mTitlePadding > rightBound.left) { bound.left = 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++) { RectF bound = bounds.get(i); // If right side is outside the screen if (bound.right > rightClip) { float 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 RectF leftBound = bounds.get(i - 1); // Intersection if (bound.left - mTitlePadding < leftBound.right) { bound.left = leftBound.right + mTitlePadding; bound.right = bound.left + w; } } } } // Now draw views for (int i = 0; i < count; i++) { // Get the title RectF 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); // Only set bold if we are within bounds mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText); // Draw text as unselected mPaintText.setColor(mColorText); canvas.drawText( mTitleProvider.getTitle(i), bound.left, 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( mTitleProvider.getTitle(i), bound.left, bound.bottom + mTopPadding, mPaintText); } } } // Draw the footer line mPath = new Path(); mPath.moveTo(0, height - mFooterLineHeight / 2f); mPath.lineTo(width, height - mFooterLineHeight / 2f); mPath.close(); canvas.drawPath(mPath, mPaintFooterLine); switch (mFooterIndicatorStyle) { case Triangle: mPath = new Path(); mPath.moveTo(halfWidth, height - mFooterLineHeight - mFooterIndicatorHeight); mPath.lineTo(halfWidth + mFooterIndicatorHeight, height - mFooterLineHeight); mPath.lineTo(halfWidth - mFooterIndicatorHeight, height - mFooterLineHeight); mPath.close(); canvas.drawPath(mPath, mPaintFooterIndicator); break; case Underline: if (!currentSelected) { break; } RectF underlineBounds = bounds.get(page); mPath = new Path(); mPath.moveTo( underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight); mPath.lineTo( underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight); mPath.lineTo( underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight); mPath.lineTo( underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight); mPath.close(); mPaintFooterIndicator.setAlpha((int) (0xFF * selectedPercent)); canvas.drawPath(mPath, mPaintFooterIndicator); mPaintFooterIndicator.setAlpha(0xFF); break; } }