viewPager 多样化导航线

#

/**
* Copyright 2016 JustWayward Team
*


* 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.
*/
package com.justwayward.reader.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.justwayward.reader.R;

import java.util.List;

/**
* Created by Administrator on 2016/8/4.
*/
public class RVPIndicator extends LinearLayout {

// 指示器风格-图标
private static final int STYLE_BITMAP = 0;
// 指示器风格-下划线
private static final int STYLE_LINE = 1;
// 指示器风格-方形背景
private static final int STYLE_SQUARE = 2;
// 指示器风格-三角形
private static final int STYLE_TRIANGLE = 3;

/*
 * 系统默认:Tab数量
 */
private static final int D_TAB_COUNT = 3;

/*
 * 系统默认:文字正常时颜色
 */
private static final int D_TEXT_COLOR_NORMAL = Color.parseColor("#000000");

/*
 * 系统默认:文字选中时颜色
 */
private static final int D_TEXT_COLOR_HIGHLIGHT = Color
        .parseColor("#FF0000");

/*
 * 系统默认:指示器颜色
 */
private static final int D_INDICATOR_COLOR = Color.parseColor("#f29b76");

/**
 * tab上的内容
 */
private List<String> mTabTitles;

/**
 * 可见tab数量
 */
private int mTabVisibleCount = D_TAB_COUNT;

/**
 * 与之绑定的ViewPager
 */
public ViewPager mViewPager;

/**
 * 文字大小
 */
private int mTextSize = 16;

/**
 * 文字正常时的颜色
 */
private int mTextColorNormal = D_TEXT_COLOR_NORMAL;

/**
 * 文字选中时的颜色
 */
private int mTextColorHighlight = D_TEXT_COLOR_HIGHLIGHT;

/**
 * 指示器正常时的颜色
 */
private int mIndicatorColor = D_INDICATOR_COLOR;

/**
 * 画笔
 */
private Paint mPaint;

/**
 * 矩形
 */
private Rect mRectF;

/**
 * bitmap
 */
private Bitmap mBitmap;

/**
 * 指示器高
 */
private int mIndicatorHeight = 5;

/**
 * 指示器宽
 */
private int mIndicatorWidth = getWidth() / mTabVisibleCount;

/**
 * 三角形的宽度为单个Tab的1/6
 */
private static final float RADIO_TRIANGEL = 1.0f / 6;

/**
 * 手指滑动时的偏移量
 */
private float mTranslationX;

/**
 * 指示器风格
 */
private int mIndicatorStyle = STYLE_LINE;

/**
 * 曲线path
 */
private Path mPath;

/**
 * viewPage初始下标
 */
private int mPosition = 0;

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

public RVPIndicator(Context context, AttributeSet attrs) {
    super(context, attrs);
    // 获得自定义属性
    TypedArray a = context.obtainStyledAttributes(attrs,
            R.styleable.RVPIndicator);

    mTabVisibleCount = a.getInt(R.styleable.RVPIndicator_item_count,
            D_TAB_COUNT);
    mTextColorNormal = a
            .getColor(R.styleable.RVPIndicator_text_color_normal,
                    D_TEXT_COLOR_NORMAL);
    mTextColorHighlight = a.getColor(
            R.styleable.RVPIndicator_text_color_hightlight,
            D_TEXT_COLOR_HIGHLIGHT);
    mTextSize = a.getDimensionPixelSize(R.styleable.RVPIndicator_text_size,
            16);
    mIndicatorColor = a.getColor(R.styleable.RVPIndicator_indicator_color,
            D_INDICATOR_COLOR);
    mIndicatorStyle = a.getInt(R.styleable.RVPIndicator_indicator_style,
            STYLE_LINE);

    Drawable drawable = a
            .getDrawable(R.styleable.RVPIndicator_indicator_src);

    if (drawable != null) {
        if (drawable instanceof BitmapDrawable) {
            mBitmap = ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable) {
            // .9图处理
            Bitmap bitmap = Bitmap.createBitmap(
                    drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight(), Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            mBitmap = bitmap;

        }
    } else {
        mBitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.heart_love);
    }

    a.recycle();

    /**
     * 设置画笔
     */
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(mIndicatorColor);
    mPaint.setStyle(Style.FILL);

}

/**
 * 初始化指示器
 */
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    switch (mIndicatorStyle) {

        case STYLE_LINE:

        /*
         * 下划线指示器:宽与item相等,高是item的1/10
         */
            mIndicatorWidth = w / mTabVisibleCount;
            mIndicatorHeight = h / 10;
            mTranslationX = 0;
            mRectF = new Rect(0, 0, mIndicatorWidth, mIndicatorHeight);

            break;
        case STYLE_SQUARE:
        case STYLE_BITMAP:

        /*
         * 方形/图标指示器:宽,高与item相等
         */
            mIndicatorWidth = w / mTabVisibleCount;
            mIndicatorHeight = h;
            mTranslationX = 0;
            mRectF = new Rect(0, 0, mIndicatorWidth, mIndicatorHeight);

            break;
        case STYLE_TRIANGLE:

        /*
         * 三角形指示器:宽与item(1/4)相等,高是item的1/4
         */
            //mIndicatorWidth = w / mTabVisibleCount / 4;
            // mIndicatorHeight = h / 4;
            mIndicatorWidth = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// 1/6 of  width  ;
            mIndicatorHeight = (int) (mIndicatorWidth / 2 / Math.sqrt(2));
            mTranslationX = 0;

            break;
    }
    // 初始化tabItem
    initTabItem();

    // 高亮
    setHighLightTextView(mPosition);
}

/**
 * 绘制指示器(子view)
 */
@Override
protected void dispatchDraw(Canvas canvas) {
    // 保存画布
    canvas.save();

    switch (mIndicatorStyle) {

        case STYLE_BITMAP:

            canvas.translate(mTranslationX, 0);
            canvas.drawBitmap(mBitmap, null, mRectF, mPaint);

            break;
        case STYLE_LINE:

            canvas.translate(mTranslationX, getHeight() - mIndicatorHeight);
            canvas.drawRect(mRectF, mPaint);

            break;
        case STYLE_SQUARE:

            canvas.translate(mTranslationX, 0);
            canvas.drawRect(mRectF, mPaint);

            break;
        case STYLE_TRIANGLE:

            canvas.translate(mTranslationX, 0);
            // 笔锋圆滑度
            // mPaint.setPathEffect(new CornerPathEffect(10));
            mPath = new Path();
            int midOfTab = getWidth() / mTabVisibleCount / 2;
            mPath.moveTo(midOfTab, getHeight() - mIndicatorHeight);
            mPath.lineTo(midOfTab - mIndicatorWidth / 2, getHeight());
            mPath.lineTo(midOfTab + mIndicatorWidth / 2, getHeight());
            mPath.close();
            canvas.drawPath(mPath, mPaint);

            break;
    }

    // 恢复画布
    canvas.restore();
    super.dispatchDraw(canvas);
}

/**
 * 设置tab上的内容
 *
 * @param datas
 */
public void setTabItemTitles(List<String> datas) {
    this.mTabTitles = datas;
}

/**
 * 设置关联viewPager
 *
 * @param viewPager
 * @param pos
 */
@SuppressWarnings("deprecation")
public void setViewPager(ViewPager viewPager, int pos) {
    this.mViewPager = viewPager;

    mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            // 设置文本高亮
            setHighLightTextView(position);

            // 回调
            if (onPageChangeListener != null) {
                onPageChangeListener.onPageSelected(position);
            }
        }

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {

            // scoll
            onScoll(position, positionOffset);

            // 回调
            if (onPageChangeListener != null) {
                onPageChangeListener.onPageScrolled(position,
                        positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            // 回调
            if (onPageChangeListener != null) {
                onPageChangeListener.onPageScrollStateChanged(state);
            }
        }
    });

    // 设置当前页
    mViewPager.setCurrentItem(pos);
    mPosition = pos;

}

/**
 *
 * 初始化tabItem
 *
 * @author Ruffian
 */
private void initTabItem() {

    if (mTabTitles != null && mTabTitles.size() > 0) {
        if (this.getChildCount() != 0) {
            this.removeAllViews();
        }

        for (String title : mTabTitles) {
            addView(createTextView(title));
        }

        // 设置点击事件
        setItemClickEvent();
    }

}

/**
 * 设置点击事件
 */
private void setItemClickEvent() {
    int cCount = getChildCount();
    for (int i = 0; i < cCount; i++) {
        final int j = i;
        View view = getChildAt(i);
        view.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewPager.setCurrentItem(j);
            }
        });
    }
}

/**
 * 设置文本高亮
 *
 * @param position
 */
private void setHighLightTextView(int position) {

    for (int i = 0; i < getChildCount(); i++) {
        View view = getChildAt(i);
        if (view instanceof TextView) {
            if (i == position) {
                ((TextView) view).setTextColor(mTextColorHighlight);
            } else {
                ((TextView) view).setTextColor(mTextColorNormal);
            }
        }
    }
}

/**
 * 滚动
 *
 * @param position
 * @param offset
 */
private void onScoll(int position, float offset) {

    // 不断改变偏移量,invalidate
    mTranslationX = getWidth() / mTabVisibleCount * (position + offset);

    int tabWidth = getWidth() / mTabVisibleCount;

    // 容器滚动,当移动到倒数第二个的时候,开始滚动
    if (offset > 0 && position >= (mTabVisibleCount - 2)
            && getChildCount() > mTabVisibleCount
            && position < (getChildCount() - 2)) {
        if (mTabVisibleCount != 1) {

            int xValue = (position - (mTabVisibleCount - 2)) * tabWidth
                    + (int) (tabWidth * offset);
            this.scrollTo(xValue, 0);

        } else {
            // 为count为1时 的特殊处理
            this.scrollTo(position * tabWidth + (int) (tabWidth * offset),
                    0);
        }
    }

    invalidate();
}

/**
 * 创建标题view
 *
 * @param text
 * @return
 */
private TextView createTextView(String text) {
    TextView tv = new TextView(getContext());
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    lp.width = getWidth() / mTabVisibleCount;
    tv.setGravity(Gravity.CENTER);
    tv.setTextColor(mTextColorNormal);
    tv.setText(text);
    tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSize);
    tv.setLayoutParams(lp);
    return tv;
}

/**
 * 对外的ViewPager的回调接口
 *
 * @author Ruffian
 *
 */
public interface PageChangeListener {
    void onPageScrolled(int position, float positionOffset,
                        int positionOffsetPixels);

    void onPageSelected(int position);

    void onPageScrollStateChanged(int state);
}

// 对外的ViewPager的回调接口
private PageChangeListener onPageChangeListener;

// 对外的ViewPager的回调接口的设置
public void setOnPageChangeListener(PageChangeListener pageChangeListener) {
    this.onPageChangeListener = pageChangeListener;
}

}

用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值