当前位置: 首页 > 工具软件 > Indicator > 使用案例 >

indicator(记录备用)

田修为
2023-12-01
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Scroller;


import java.util.ArrayList;
import java.util.List;


public class SearchTypeIndicator extends ViewGrop implements View.OnClickListener {

    private static final float TITLE_TEXT_SCALE_ADJUST = 0.143f;
    private static final float VISIBLE_ANIM_DELAY_PERCENT = 0.4f;
    private Scroller mScroller;
    private VelocityTracker mVelocityTracker;
    private Context mContext;
    private Paint mSliderPaint;
    private Paint mCoverPaint;
    private int mTouchSlop = 0;
    private float mLastMotionX = 0;
    private int mMaxVelocityX = 3000;
    private int mTotalWidth;
    private int mHeight;
    private int mWidth;
    private List<SearchTypeIndicatorItem> mTitleViewList;
    private boolean isfling = false;
    private static final int TOUCH_STATE_REST = 0;
    private static final int TOUCH_STATE_SCROLLING = 1;
    private int mTouchState = TOUCH_STATE_REST;
    private List<Integer> mTabsWidth;
    private int mSliderPaddingSize;
    private float mSliderStartX = 0;
    private float mSliderStopX = 0;
    private float mSliderY = 0;
    private int mSliderOffsetX = -1;
//    private CustomViewPager mViewPager;
    private int mLastTabTitlePosition = 0;
    private int mCurSelectedTabPosition = 0;
    private DecelerateInterpolator mDecelerateInterpolator;
    private OvershootInterpolator mOvershootInterpolator;
    private PorterDuffXfermode mPorterDuffXfermode;
    private long mStartTime;
    private int mDistance;
    private boolean mTouchUpFlag = false;
    private Bitmap mCoverLeft;
    private Bitmap mCoverRight;
    private int mCoverWidth;
    private int mCoverMarginBottom;
    private Rect mRect = new Rect();
    private int mTextInterval;
    private float mVisiblePercent = 1;
    private int[] mVisibleIndex = {-1, -1};
    private int mTextTranslationYDis;
    private boolean canBeTouch = true;
    private boolean needUpdateVisibleIndex = true;
    private ArgbEvaluator mArgbEvaluator;
    private int mTextSelectedColor;
    private int mTextColor;
    private int mTextAlpha;
 

    public SearchTypeIndicator(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public SearchTypeIndicator(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SearchTypeIndicator(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init();
    }

    private void init() {
        mScroller = new Scroller(mContext);
        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        mMaxVelocityX = ViewConfiguration.get(getContext()).getScaledMaximumFlingVelocity() / 3;
        mTabsWidth = new ArrayList<>();
        mDecelerateInterpolator = new DecelerateInterpolator();
        mOvershootInterpolator = new OvershootInterpolator();
        mPorterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
        mSliderPaddingSize = (int) mContext.getResources().getDimension(R.dimen.navigation_news_tabs_title_underline_padding);
        mCoverLeft = BitmapFactory.decodeResource(getResources(), R.drawable.news_tabs_title_cover_left);
        mCoverRight = BitmapFactory.decodeResource(getResources(), R.drawable.news_tabs_title_cover_right);
        mCoverWidth = (int) mContext.getResources().getDimension(R.dimen.navigation_tabs_title_cover_width);
        mCoverMarginBottom = (int) mContext.getResources().getDimension(R.dimen.navigation_news_tabs_title_underline_height);
        mCoverPaint = new Paint();
        mCoverPaint.setAntiAlias(true);
        mSliderPaint = new Paint();
        mSliderPaint.setStrokeWidth((int) ViewUtil.dp2px(mContext, 2));
        mSliderPaint.setAntiAlias(true);
//        mSliderPaint.setColor(mContext.getResources().getColor(R.color.white));
        mTextInterval = (int) ViewUtil.dp2px(mContext, 29);
        mTextTranslationYDis = (int) ViewUtil.dp2px(mContext, 10);
        mArgbEvaluator = new ArgbEvaluator();
        if (mTitleViewList == null) {
            mTitleViewList = new ArrayList<>();
        }
    }

    public void updateTitleViewList(int textSize) {
        mTitleViewList.clear();
        this.removeAllViews();
//        mTextColor = Color.parseColor("#999999");
//        mTextSelectedColor = Color.parseColor("#2087E7");
        mTextAlpha = 153;
        if (mSearchTypeModel != null && mSearchTypeModel.getChannels() != null &&  mSearchTypeModel.getChannels().size() != 0) {
            Log.i("search","updateTitleViewList: mCurSelectedTabPosition="+mCurSelectedTabPosition);
            for (int i = 0; i <  mSearchTypeModel.getChannels().size(); i++) {
                SearchTypeIndicatorItem item = new SearchTypeIndicatorItem(mContext);
                if (i != mCurSelectedTabPosition) {
//                    item.setTitleTextColor(mTextColor, mTextAlpha);
                    item.setTitleTextColor(mTextColor, 255);
                } else {
                    item.setTitleTextColor(mTextSelectedColor, 255);
                }
                LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
//                layoutParams.height = (int) getContext().getResources().getDimension(R.dimen.search_bar_container_height);
                item.setGravity(Gravity.CENTER);
//                item.getPaint().setTextSize(mContext.getResources().getDimension(R.dimen.navigation_news_tabs_title_text_size));
                item.getPaint().setTextSize((int) ViewUtil.dp2px(mContext, textSize));
                item.setIndex(i);
                item.setString( mSearchTypeModel.getChannels().get(i).getChannel_name());
                Log.i("search","updateTitleViewList: name="+mSearchTypeModel.getChannels().get(i).getChannel_name());
                item.setOnClickListener(this);
                mTitleViewList.add(item);
                addView(item, layoutParams);
            }
            mSliderPaint.setColor(Color.parseColor("#2087E7"));
//            mSliderPaint.setColor(textSelectedColor);
        }
        layout(getLeft(), getTop(), getRight(), getBottom());
        forceLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measureWidth = measureWidth(widthMeasureSpec);
        int measureHeight = measureHeight(heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth, measureHeight);
    }

    private int measureWidth(int pWidthMeasureSpec) {
        int result = 0;
        int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);
        int widthSize = MeasureSpec.getSize(pWidthMeasureSpec);
        switch (widthMode) {
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY:
                result = widthSize;
                break;
        }
        return result;
    }

    private int measureHeight(int pHeightMeasureSpec) {
        int result = 0;
        int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);
        int heightSize = MeasureSpec.getSize(pHeightMeasureSpec);

        switch (heightMode) {
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY:
                result = heightSize;
                break;
        }
        return result;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int totalWidth = 0;
        int childCount = getChildCount();
        mTabsWidth.clear();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            int textWidth = 0;
            textWidth = Math.round(((SearchTypeIndicatorItem) childView).getTextWidth());
            textWidth += mTextInterval;
            childView.layout(totalWidth, t, totalWidth + textWidth, b);
            totalWidth += textWidth;
            Integer integer = totalWidth;
            mTabsWidth.add(integer);
        }
        mTotalWidth = totalWidth;
        if (mLastTabTitlePosition >= childCount) {
            mLastTabTitlePosition = childCount - 1;
            if (mLastTabTitlePosition < 0) {
                mLastTabTitlePosition = 0;
            }
        }
//        scrollTabsTitle(mLastTabTitlePosition, 0);
    }

    public int getTitlesWidth() {
        return mTotalWidth > getWidth() ? getWidth() : mTotalWidth;
    }

    public void snapToDestination(int destX) {
        isfling = true;
        mScroller.fling(getScrollX(), 0, destX, 0, -mWidth, mTotalWidth - getTitlesWidth() + mWidth, 0, 0);
//        BLog.d("xuekai", "NewsTabsTitleview -> snapToDestination finalX:" + mScroller.getFinalX() + " finalY:" + mScroller.getFinalY() + " Duration:" + mScroller.getDuration());
        if (mTouchUpFlag) {
            mStartTime = System.currentTimeMillis();
            if (mScroller.getFinalX() < 0) {
                mDistance = -getScrollX();
            } else if (mScroller.getFinalX() > mTotalWidth - getTitlesWidth()) {
                mDistance = mTotalWidth - getScrollX() - getTitlesWidth();
            }
        }
        invalidate();
    }

    private void smoothToEdge() {
        int dx = 0;
        if (getScrollX() < 0) {
            dx = -getScrollX();
        } else if (getScrollX() > mTotalWidth - getTitlesWidth()) {
            dx = mTotalWidth - getTitlesWidth() - getScrollX();
        }
        mScroller.startScroll(getScrollX(), getScrollY(), dx, 0, 600);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
//            BLog.d("", "NewsTabsTitleview -> computeScroll finalX:" + mScroller.getFinalX() + " finalY:" + mScroller.getFinalY() + " Duration:" + mScroller.getDuration());
            int dest;
            if (mTouchUpFlag && (mScroller.getFinalX() < 0 || mScroller.getFinalX() > mTotalWidth - getTitlesWidth())) {
                float scale = (float) (System.currentTimeMillis() - mStartTime) / mScroller.getDuration();
                if (scale > 1) {
                    scale = 1;
                }
                scale = mOvershootInterpolator.getInterpolation(scale);
                if (mScroller.getFinalX() < 0) {
                    dest = 0;
                } else {
                    dest = mTotalWidth - getTitlesWidth();
                }
//                BLog.d("", "NewsTabsTitleview -> computeScroll scale:" + scale + " mDistance:" + mDistance + " currX:" + (int) (startDis + mDistance * scale));
                scrollTo((int) (dest + mDistance * (scale - 1)), mScroller.getCurrY());
            } else {
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            }
            postInvalidate();
        } else {
            if (isfling) {
                if (getScrollX() < 0 || getScrollX() > mTotalWidth - getTitlesWidth()) {
                    smoothToEdge();
                }
                isfling = false;
            }
            mTouchUpFlag = false;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (!canBeTouch) {
            return false;
        }
        final int action = ev.getAction();
        if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
            return true;
        }
        final float x = ev.getX();
        switch (action) {
            case MotionEvent.ACTION_MOVE:
                final int xDiff = (int) Math.abs(mLastMotionX - x);
                if (xDiff > mTouchSlop) {
                    mTouchState = TOUCH_STATE_SCROLLING;
                }
                break;

            case MotionEvent.ACTION_DOWN:
                mLastMotionX = x;
                mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mTouchState = TOUCH_STATE_REST;
                break;
        }
        return mTouchState != TOUCH_STATE_REST;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!canBeTouch) {
            return false;
        }
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.computeCurrentVelocity(1000);
        mVelocityTracker.addMovement(event);

        super.onTouchEvent(event);
        float x = event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isfling = false;
                if (mScroller != null) {
                    if (!mScroller.isFinished()) {
                        mScroller.abortAnimation();
                    }
                }
                mLastMotionX = x;
                break;
            case MotionEvent.ACTION_MOVE:
                int xDiff = (int) (mLastMotionX - x);
                float scale = 0;
                if (getScrollX() < 0) {
                    int dis = Math.abs(getScrollX());
                    if (dis > getTitlesWidth() / 3) {
                        dis = getTitlesWidth() / 3;
                    }
                    scale = mDecelerateInterpolator.getInterpolation((float) dis / (getTitlesWidth() / 3));
                } else if (getScrollX() + getTitlesWidth() > mTotalWidth) {
                    int dis = Math.abs(getTitlesWidth() + getScrollX() - mTotalWidth);
                    if (dis > getTitlesWidth() / 3) {
                        dis = getTitlesWidth() / 3;
                    }
                    scale = mDecelerateInterpolator.getInterpolation((float) dis / (getTitlesWidth() / 3));
                }
                scrollBy((int) ((1 - scale) * xDiff), 0);
                mLastMotionX = x;
                break;
            case MotionEvent.ACTION_UP:
                int velocityX = (int) mVelocityTracker.getXVelocity();
                int destX = velocityX;
                if (velocityX > mMaxVelocityX) {
                    destX = mMaxVelocityX;
                } else if (velocityX < -mMaxVelocityX) {
                    destX = -mMaxVelocityX;
                }
                if (getScrollX() < 0 || getScrollX() + getTitlesWidth() > mTotalWidth) {
                    snapToDestination(-destX / 8);
                } else {
                    mTouchUpFlag = true;
                    snapToDestination(-destX);
                }
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                mTouchState = TOUCH_STATE_REST;
                break;
            case MotionEvent.ACTION_CANCEL:
                mTouchState = TOUCH_STATE_REST;
                break;
        }

        return true;
    }

//    @Override
//    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
//        float lineWidth = mSliderPaint.getStrokeWidth();
//        canvas.drawLine(mSliderStartX, mSliderY - lineWidth / 2.f, mSliderStopX, mSliderY - lineWidth / 2.f, mSliderPaint);
//    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int saveCount = canvas.saveLayer(getScrollX(), 0, getScrollX() + mWidth, mHeight, mCoverPaint, Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        mCoverPaint.setXfermode(mPorterDuffXfermode);
        mRect.set(getScrollX(), 0, getScrollX() + mCoverWidth, mHeight - mCoverMarginBottom);
        canvas.drawBitmap(mCoverLeft, null, mRect, mCoverPaint);
        mRect.set(getScrollX() + mWidth - mCoverWidth, 0, getScrollX() + mWidth, mHeight - mCoverMarginBottom);
        canvas.drawBitmap(mCoverRight, null, mRect, mCoverPaint);
        mCoverPaint.setXfermode(null);
        canvas.restoreToCount(saveCount);
        float lineWidth = mSliderPaint.getStrokeWidth();
//        canvas.drawLine(mSliderStartX, mSliderY - lineWidth / 2.f, mSliderStopX, mSliderY - lineWidth / 2.f, mSliderPaint);
    }

    public void scrollTabsTitle(int position, float positionOffset) {
        scrollTabsTitle(position, positionOffset, false, 0, 0);
    }

    public void scrollTabsTitle(int position, float positionOffset, boolean isOptimizeAnim, int startPosition, int targetPosition) {
        if (mTabsWidth != null && position < mTabsWidth.size() && startPosition < mTabsWidth.size() && targetPosition < mTabsWidth.size()) {
            if (!isOptimizeAnim) {
                if (mLastTabTitlePosition != position && mLastTabTitlePosition < mTitleViewList.size()) {
                    mTitleViewList.get(mLastTabTitlePosition).setTitleTextColor(mTextColor, mTextAlpha);
//                    mTitleViewList.get(mLastTabTitlePosition).getTextPaint().setAlpha((mTabsTitleAlphaBase));
                    mTitleViewList.get(mLastTabTitlePosition).setScaleX(1.0f);
                    mTitleViewList.get(mLastTabTitlePosition).setScaleY(1.0f);
                    mTitleViewList.get(mLastTabTitlePosition).postInvalidate();
                }
                mLastTabTitlePosition = position;
                if (position < mCurSelectedTabPosition - 1) {
                    mCurSelectedTabPosition = position + 1;
                    mSliderOffsetX = -1;
                } else if (position > mCurSelectedTabPosition) {
                    mCurSelectedTabPosition = position;
                    mSliderOffsetX = -1;
                }

                int xPosition = mTabsWidth.get(position).intValue();
                int curTabWidth = xPosition;
                float curTabTextWidth = mTitleViewList.get(position).getTextWidth();
                int startX = 0;
                if (position > 0) {
                    startX = mTabsWidth.get(position - 1).intValue();
                }
                curTabWidth = xPosition - startX;
                int afterTabWith = curTabWidth;
                float afterTabTextWidth = curTabTextWidth;
                if (position < mTabsWidth.size() - 1) {
                    afterTabWith = mTabsWidth.get(position + 1).intValue() - xPosition;
                    afterTabTextWidth = mTitleViewList.get(position + 1).getTextWidth();
                }
                int offsetX = (int) (startX + curTabWidth * positionOffset);
                mSliderY = getHeight();
//                mSliderStartX = offsetX + mSliderPaddingSize;
//                mSliderStopX = mSliderStartX + curTabWidth - mSliderPaddingSize * 2 + (afterTabWith - curTabWidth) * positionOffset;
                int curTabPaddingSize = Math.round((curTabWidth - curTabTextWidth) / 2.f) - mSliderPaddingSize;
                int afterTabPaddingSize = Math.round((afterTabWith - afterTabTextWidth) / 2.f) - mSliderPaddingSize;
                int paddingSize = Math.round(curTabPaddingSize + (afterTabPaddingSize - curTabPaddingSize) * positionOffset);
                mSliderStartX = offsetX + paddingSize;
                mSliderStopX = mSliderStartX + curTabWidth - paddingSize * 2 + (afterTabWith - curTabWidth) * positionOffset;

                if (mSliderOffsetX < 0) {
                    if (mCurSelectedTabPosition > 0) {
                        mSliderOffsetX = mTabsWidth.get(mCurSelectedTabPosition - 1) - getScrollX();
                    } else {
                        mSliderOffsetX = 0;
                    }
                    if (mSliderOffsetX < 0) {
                        mSliderOffsetX = 0;
                    } else if (mSliderOffsetX > getTitlesWidth() - curTabWidth) {
                        mSliderOffsetX = getTitlesWidth() - curTabWidth;
                    }
                }
                if (mTotalWidth > getTitlesWidth()) {
                    if (offsetX < getScrollX()) {
                        scrollTo(offsetX, getScrollY());
                    } else if (mCurSelectedTabPosition <= position || offsetX > getScrollX() + mSliderOffsetX) {
                        if (offsetX - mSliderOffsetX + getTitlesWidth() > mTotalWidth) {
                            offsetX = mTotalWidth - getTitlesWidth() + mSliderOffsetX;
                        }
                        scrollTo(offsetX - mSliderOffsetX, getScrollY());
                    }
                } else {
                    scrollTo(0, getScrollY());
                }
                mTitleViewList.get(position).setTitleTextColor((Integer) mArgbEvaluator.evaluate(1 - positionOffset, mTextColor, mTextSelectedColor),
                        mTextAlpha == 255 ? mTextAlpha : Math.round(mTextAlpha + (255 - mTextAlpha) * (1 - positionOffset)));
//                mTitleViewList.get(position).getTextPaint().setAlpha((int) (mTabsTitleAlphaBase + mTabsTitleAlphaAdjust * (1 - positionOffset)));
//                mTitleViewList.get(position).setScaleX(1.0f + TITLE_TEXT_SCALE_ADJUST * (1.0f - positionOffset));
//                mTitleViewList.get(position).setScaleY(1.0f + TITLE_TEXT_SCALE_ADJUST * (1.0f - positionOffset));
                mTitleViewList.get(position).postInvalidate();
                if (position < mTabsWidth.size() - 1) {
                    mTitleViewList.get(position + 1).setTitleTextColor((Integer) mArgbEvaluator.evaluate(positionOffset, mTextColor, mTextSelectedColor),
                            mTextAlpha == 255 ? mTextAlpha : Math.round(mTextAlpha + (255 - mTextAlpha) * positionOffset));
//                    mTitleViewList.get(position + 1).getTextPaint().setAlpha((int) (mTabsTitleAlphaBase + mTabsTitleAlphaAdjust * positionOffset));
//                    mTitleViewList.get(position + 1).setScaleX(1.0f + TITLE_TEXT_SCALE_ADJUST * positionOffset);
//                    mTitleViewList.get(position + 1).setScaleY(1.0f + TITLE_TEXT_SCALE_ADJUST * positionOffset);
                    mTitleViewList.get(position + 1).postInvalidate();
                }

                if (positionOffset == 0) {
                    mSliderOffsetX = -1;
                    mCurSelectedTabPosition = position;
                }

            } else {
                int distanceRightX = mTabsWidth.get(targetPosition).intValue() - mTabsWidth.get(startPosition).intValue();
                int distanceLeftX;
                int startRightX = mTabsWidth.get(startPosition).intValue();
                int startLeftX;
                if (targetPosition < startPosition && position == targetPosition) {
                    positionOffset = 1.f - positionOffset;
                }
                if (targetPosition == 0) {
                    distanceLeftX = 0 - mTabsWidth.get(startPosition - 1).intValue();
                    startLeftX = mTabsWidth.get(startPosition - 1).intValue();
                } else if (startPosition == 0) {
                    distanceLeftX = mTabsWidth.get(targetPosition - 1).intValue() - 0;
                    startLeftX = 0;
                } else {
                    distanceLeftX = mTabsWidth.get(targetPosition - 1).intValue() - mTabsWidth.get(startPosition - 1).intValue();
                    startLeftX = mTabsWidth.get(startPosition - 1).intValue();
                }
                if (position == targetPosition && positionOffset == 0) {
                    positionOffset = 1;
                }
                mTitleViewList.get(startPosition).setTitleTextColor((Integer) mArgbEvaluator.evaluate(1 - positionOffset, mTextColor, mTextSelectedColor),
                        mTextAlpha == 255 ? mTextAlpha : Math.round(mTextAlpha + (255 - mTextAlpha) * (1 - positionOffset)));
//                mTitleViewList.get(startPosition).getTextPaint().setAlpha((int) (mTabsTitleAlphaBase + mTabsTitleAlphaAdjust * (1 - positionOffset)));
                mTitleViewList.get(startPosition).setScaleX(1.0f + TITLE_TEXT_SCALE_ADJUST * (1.0f - positionOffset));
                mTitleViewList.get(startPosition).setScaleY(1.0f + TITLE_TEXT_SCALE_ADJUST * (1.0f - positionOffset));
                mTitleViewList.get(startPosition).postInvalidate();

                mTitleViewList.get(targetPosition).setTitleTextColor((Integer) mArgbEvaluator.evaluate(positionOffset, mTextColor, mTextSelectedColor),
                        mTextAlpha == 255 ? mTextAlpha : Math.round(mTextAlpha + (255 - mTextAlpha) * positionOffset));
//                mTitleViewList.get(targetPosition).getTextPaint().setAlpha((int) (mTabsTitleAlphaBase + mTabsTitleAlphaAdjust * positionOffset));
                mTitleViewList.get(targetPosition).setScaleX(1.0f + TITLE_TEXT_SCALE_ADJUST * positionOffset);
                mTitleViewList.get(targetPosition).setScaleY(1.0f + TITLE_TEXT_SCALE_ADJUST * positionOffset);
                mTitleViewList.get(targetPosition).postInvalidate();

                int scrollDistance = 0;
                if (startLeftX + distanceLeftX < getScrollX()) {
                    scrollDistance = startLeftX + distanceLeftX - getScrollX();
                } else if (startRightX + distanceRightX > getScrollX() + getTitlesWidth()) {
                    scrollDistance = startRightX + distanceRightX - getScrollX() - getTitlesWidth();
                }

                mSliderY = getHeight();
//                mSliderStartX = startLeftX + mSliderPaddingSize + distanceLeftX * positionOffset;
//                mSliderStopX = startRightX - mSliderPaddingSize + distanceRightX * positionOffset;
                int curTabPaddingSize = Math.round(((startRightX - startLeftX) - mTitleViewList.get(startPosition).getTextWidth()) / 2.f) - mSliderPaddingSize;
                int afterTabPaddingSize = Math.round(((startRightX + distanceRightX - startLeftX - distanceLeftX) - mTitleViewList.get(targetPosition).getTextWidth()) / 2.f) - mSliderPaddingSize;
                int paddingSize = Math.round(curTabPaddingSize + (afterTabPaddingSize - curTabPaddingSize) * positionOffset);
                mSliderStartX = startLeftX + paddingSize + distanceLeftX * positionOffset;
                mSliderStopX = startRightX - paddingSize + distanceRightX * positionOffset;
                scrollTo((int) (getScrollX() + scrollDistance * positionOffset), getScrollY());

                mLastTabTitlePosition = targetPosition;

            }
            invalidate();
        }
    }

    @Override
    public void onClick(View v) {
        if (v instanceof SearchTypeIndicatorItem) {
            SearchTypeIndicatorItem item = (SearchTypeIndicatorItem) v;
            scrollTabsTitle(item.getIndex(),0);
//            setCurSelectedTabPosition(item.getIndex());
            if(mOnSearchTypeClickListener != null){
                mOnSearchTypeClickListener.onclick(item.getIndex());
            }

//            updateTitleViewList();
//            if (mViewPager != null && mViewPager.getAdapter() != null && mViewPager.getAdapter().getCount() > item.getIndex()
//                    && item.getIndex() != mViewPager.getCurrentItem()) {
//                if (Math.abs(mViewPager.getCurrentItem() - item.getIndex()) > 1) {
//                    mViewPager.setCurrentItem(item.getIndex(), false);
//                } else {
//                    mViewPager.setCurrentItem(item.getIndex(), true);
//                }
//            }
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight = h;
        mWidth = w;
    }


    public void setCurSelectedTabPosition(int position) {
        mCurSelectedTabPosition = position;
        if (mTitleViewList.size() > position && mTitleViewList.get(position) != null) {
        }

        for (int i = 0; i < getChildCount(); i++) {
//            ((SearchTypeIndicatorItem) getChildAt(i)).setPointColor(pointColor);
            if (i != mCurSelectedTabPosition) {
                ((SearchTypeIndicatorItem) getChildAt(i)).setTitleTextColor(mTextColor, mTextAlpha);
            } else {
                ((SearchTypeIndicatorItem) getChildAt(i)).setTitleTextColor(mTextSelectedColor, 255);
            }
            mSliderPaint.setColor(mTextSelectedColor);
            getChildAt(i).invalidate();
        }

//        scrollTabsTitle(position,0);
        invalidate();
    }

    private int[] getCurVisibleViewIndex() {
        int[] index = {-1, -1};
        if (mTabsWidth == null) {
            return index;
        }
        int position = 0;
        while (position < mTabsWidth.size()) {
            if (index[0] == -1 && getScrollX() < mTabsWidth.get(position)) {
                index[0] = position;
            }
            if (index[1] == -1 && getScrollX() + getTitlesWidth() <= mTabsWidth.get(position)) {
                index[1] = position;
            }
            View view = getChildAt(position);
            view.setAlpha(1);
            view.setTranslationY(0);
            position++;
        }
        return index;
    }

    public void setVisiblePercent(float percent) {
        if (mVisiblePercent != percent && mTabsWidth != null) {
            mVisiblePercent = percent;
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
            if (needUpdateVisibleIndex) {
                mVisibleIndex = getCurVisibleViewIndex();
                needUpdateVisibleIndex = false;
            }
            mSliderPaint.setAlpha((int) (mVisiblePercent * 255));

            if (mVisibleIndex[0] >= 0 && mVisibleIndex[1] >= mVisibleIndex[0] && mVisibleIndex[1] < mTabsWidth.size()) {
                float delayTime = VISIBLE_ANIM_DELAY_PERCENT;
                if (mVisibleIndex[1] - mVisibleIndex[0] > 0) {
                    delayTime = VISIBLE_ANIM_DELAY_PERCENT / (mVisibleIndex[1] - mVisibleIndex[0]);
                }
                for (int curIndex = mVisibleIndex[0], i = 0; curIndex <= mVisibleIndex[1]; curIndex++, i++) {
                    View view = getChildAt(curIndex);
                    float curViewPercent = (percent - delayTime * i) / (1 - VISIBLE_ANIM_DELAY_PERCENT);
                    curViewPercent = curViewPercent > 1 ? 1 : curViewPercent;
                    curViewPercent = curViewPercent < 0 ? 0 : curViewPercent;
                    view.setAlpha(mDecelerateInterpolator.getInterpolation(curViewPercent));
                    view.setTranslationY(mTextTranslationYDis * (1 - curViewPercent));
                }
            }
            postInvalidate();
        }
    }

    public void setCanBeTouch(boolean touch) {
        canBeTouch = touch;
        if (!canBeTouch) {
            needUpdateVisibleIndex = true;
            if (mTotalWidth != 0) {
                if (getScrollX() < 0) {
                    scrollTo(0, 0);
                } else if (getScrollX() + getTitlesWidth() > mTotalWidth) {
                    scrollTo(mTotalWidth - getTitlesWidth(), 0);
                }
            }
        }
    }
    
}
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

public class SearchTypeIndicatorItem extends TextView {
    private int mIndex;
    private String mString;

    public void setString(CharSequence mString) {
        this.mString = mString.toString();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        setText(mString);
    }

    public SearchTypeIndicatorItem(Context context) {
        this(context, null);
    }

    public SearchTypeIndicatorItem(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setIndex(int index) {
        mIndex = index;
    }

    public int getIndex() {
        return mIndex;
    }

    public void setTitleTextColor(int color, int alpha) {
//        setTextColor((color & 0x00ffffff) | (alpha << 24));
        setTextColor(color);
    }

    public float getTextWidth() {
        return getPaint().measureText(mString);
    }
}




 类似资料: