自定义控件-ViewPagerIndicator(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012153184/article/details/52488968

自定义控件-ViewPagerIndicator(一)

本文摘录自元斌的博客 地址:
http://blog.csdn.net/qibin0506/article/details/42046559

二话不说先上效果图

上面的效果并没有加入fragment ,那是下一篇文章所记录的知识点,这个功能的亮点就在于 底部横线的滑动 ,虽然很简单但是总体的实现还是很有学习意义的。那么下来来看代码吧 。

先看整体的代码

public class ViewPagerIndicator extends LinearLayout {

    private int mColor;//指示器的颜色
    private int mItemCount;//tab的个数
    private int DEFAULT_TAB_COUNT = 4;//默认的tab的个数
    private int DEFAULT_INDICATOR_COLCR = 0x0000FF;//默认的indicator的颜色
    private int mHeight = 5; // 指示符的高度,固定了
    private int mTop;//整个Tab的高度
    private int mWidth;//Indicator的宽
    private Paint mPaint;//Indicator的画笔
    private int mChildCount;//XML中的tab个数
    private int mLeft; // 指示符的left

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

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

    public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray tA = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator, 0, 0);
        mColor = tA.getColor(R.styleable.ViewPagerIndicator_indicator_color, DEFAULT_INDICATOR_COLCR);
        mItemCount = tA.getInt(R.styleable.ViewPagerIndicator_item_count, DEFAULT_TAB_COUNT);
        tA.recycle();
        //初始化画笔
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setAntiAlias(true);//抗锯齿设置
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mChildCount = getChildCount();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mTop = getMeasuredHeight(); // 测量的高度即指示符的顶部位置
        int width = getMeasuredWidth(); // 获取测量的总宽度
        int height = mTop + mHeight; // 重新定义一下测量的高度
        mWidth = width / mChildCount; // 指示符的宽度为总宽度/item的个数
        setMeasuredDimension(width, height);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        Rect rect = new Rect(mLeft, mTop, mWidth + mLeft, mTop + mHeight);
        canvas.drawRect(rect, mPaint);
        super.dispatchDraw(canvas);
    }

    /**
     * 指示符滚动
     *
     * @param position 现在的位置
     * @param offset   偏移量 0 ~ 1
     */
    public void scroll(int position, float offset) {
        mLeft = (int) ((position + offset) * mWidth);
        invalidate();
    }

众所周知要实现自定义控件 就要先集成 某个控件或者 集成View 这里我们集成 Linearlayout 重写三个构造方法

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

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

public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) 

在第三个构造中 初始化控件的属性

ublic ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
    TypedArray tA = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator, 0, 0);
mColor = tA.getColor(R.styleable.ViewPagerIndicator_indicator_color, DEFAULT_INDICATOR_COLCR);
mItemCount = tA.getInt(R.styleable.ViewPagerIndicator_item_count, DEFAULT_TAB_COUNT);
    tA.recycle();
//初始化画笔
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setAntiAlias(true);//抗锯齿设置
}

属性的定义attr代码如下:
itemcount (抱歉此参数多余)

<declare-styleable name="ViewPagerIndicator">
    <attr name="item_count" format="integer"></attr>
    <attr name="indicator_color" format="color"></attr>
</declare-styleable>

重写onFinishInflate() 重新计算item的个数

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

 mChildCount = getChildCount();

}

onMeasure测量linerlayout的宽高并重新定义

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mTop = getMeasuredHeight(); // 测量的高度即指示符的顶部位置
int width = getMeasuredWidth(); // 获取测量的总宽度
int height = mTop + mHeight; // 重新定义一下测量的高度
mWidth = width / mChildCount; // 指示符的宽度为总宽度/item的个数
setMeasuredDimension(width, height);
}

接下来绘制indicator

@Override
protected void dispatchDraw(Canvas canvas) {
    Rect rect = new Rect(mLeft, mTop, mWidth + mLeft, mTop + mHeight);
    canvas.drawRect(rect, mPaint);
super.dispatchDraw(canvas);
}

这里要特别说明下ondraw()和 dispathdraw() 的区别
ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法。
下面就是关键点的所在了
自定义一个方法 scroll()把viewpage的滑动参数传递进来 动态的改变左侧左边的值就会看到咱们想要的结果了。 that’all is over!

/**
 * 指示符滚动
 *
 * @param position 现在的位置
 * @param offset   偏移量 0 ~ 1
 */
public void scroll(int position, float offset) {
mLeft = (int) ((position + offset) * mWidth);
    invalidate();
}

***************使用***************************

XML代码

<com.yyr.custom.view.ViewPagerIndicator
xmlns:indicator="http://schemas.android.com/apk/res-auto"
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dip"
android:paddingTop="10dip"
android:weightSum="4"
indicator:indicator_color="#FFFF0000" >
    <TextView
android:id="@+id/tab_one"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="TAB1" />

    <TextView
android:id="@+id/tab_two"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="TAB2" />

    <TextView
android:id="@+id/tab_three"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="TAB3" />

    <TextView
android:id="@+id/tab_four"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:text="TAB4" />
</com.yyr.custom.view.ViewPagerIndicator>

activity中调用

mViewPage.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
    }

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mIndicator.scroll(position, positionOffset);
    }

@Override
public void onPageScrollStateChanged(int position) {

    }
});

简单易理解才是一种提高!

猜你喜欢

转载自blog.csdn.net/u012153184/article/details/52488968