CharmingAndroid框架类整理之VPIndicator类——ViewPager的指示器

功能介绍

VPIndicator类是一个VierPager的指示器,利用Builder设计模式方便连续设置常用属性。

方法名功能默认值
setText(List titles)添加标题null
setVisible_item(int count)可见的标题栏数4
setTextSize(float sp)标题文字大小16sp
setTextNormalColor (int color)未选中时标题颜色0xff000000
setTextLightColor (int color)选中时标题颜色0xffff9000
setIndicatorHeight(int dp)指示器横条高度3dp
setIndicatorColor (int color)指示器颜色0x77f98740
setMovePattern(int pattern)移动样式MOVE_SMOOTH
setMoveDuration(int duration)移动时间(当MOVE_DELAY时有效)500
setIndicatorUnder(boolean under)是否在标题栏之下false
setVPListener(VPListener listener)设置ViewPager滑动监听器null
setBackgroundColor(int color)设置背景颜色0xfff8f8f8
setViewPager(ViewPager vp, int position)设置ViewPagernull
setVPListener(VPListener listener)设置ViewPager滑动监听器null

代码解析

初始变量及构造方法

public class VPIndicator extends LinearLayout {

    private Context context;
//  装载TextView的容器布局
    private LinearLayout ll;
//  移动的指示器
    private ImageView iv;
//  每一个item的宽度,将在onSizeChanged()里计算得到
    private float item_width;
//  xp与dp、sp的比值,用于设置高度
    private float scale;
//  现在所选中的位置,默认为0。主要用于移动动画,在设置初始滑动位置时也有使用
    private int nowPosition=0;
    public static final int MOVE_SMOOTH=0;
    public static final int MOVE_QUICK=1;
    public static final int  MOVE_DELAY=2;

    //默认值
    private ViewPager mViewPager=null;
    private VPListener mListener=null;
    private int backGroundColor = 0xfff8f8f8;
    private int moveDuration=500;
    private int movePattern=MOVE_SMOOTH;
    private boolean iv_under=false;
    private int iv_height = 3;
    private int visible_item = 4;
    private float textSize = 16f;
    private int textNormalColor = 0xff000000;
    private int textLightColor = 0xffff9000;
    private int ivColor = 0x77f98740;

    public VPIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.context = context;
        setOrientation(LinearLayout.VERTICAL);
        setBackgroundColor(backGroundColor);
        scale = getResources().getDisplayMetrics().density;
        ll = new LinearLayout(context);
        iv = new ImageView(context);
        LinearLayout.LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        params.weight=1;
        params.height=0;
        ll.setLayoutParams(params);
        addView(ll);
        addView(iv);
    }
}

VPIndicator继承自LinearLayout,构造函数方法通过addView添加了ll(TextView容器)、iv(指示器部分),并设置了ll的布局属性。

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        // 计算每个标题的宽度
        item_width = w / visible_item;

//      设置TextView的宽度和字体大小
        for (int i = 0; i < ll.getChildCount(); i++) {
            TextView tv = (TextView) ll.getChildAt(i);
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
            LinearLayout.LayoutParams tvParams = (LayoutParams) tv.getLayoutParams();
            tvParams.width = (int) item_width;
            tv.setLayoutParams(tvParams);
        }
//      由于初始时setCurrentItem(0, false)时不能触发onPageSelected(int arg0)回调,所以需要预先设置选中第一标题
        setLightText(0);

//      设置iv指示器的宽高、上边间距、背景颜色
        LinearLayout.LayoutParams ivParams = (LayoutParams) iv.getLayoutParams();
        ivParams.height = (int) (iv_height * scale);
        ivParams.width = (int) item_width;
        if(!iv_under)
            ivParams.topMargin=(int) (-iv_height*scale);
        iv.setLayoutParams(ivParams);
        iv.setBackgroundColor(ivColor);
//      设置mViewPager的初始页面
        mViewPager.setCurrentItem(nowPosition, false);
    }

不在 setViewPager(ViewPager vp, int position)里设置mViewPager.setCurrentItem(nowPosition, false)的原因是:onPageSelected(int arg0)会在onSizeChanged执行之前调用,会导致当position不为0时iv的初始位置设置不成功。

    @SuppressWarnings("deprecation")
    public VPIndicator setViewPager(ViewPager vp, int position) {
        mViewPager = vp;
        nowPosition=position;
//      初始mViewPager.setCurrentItem(0)时,不调用onPageSelected,只调用onPageScrolled
//      初始mViewPager.setCurrentItem(1)时,都调用,如果viewpager还未加载,onPageSelected在viewpager加载前就会直接调用,onPageScrolled在加载后调用
        vp.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                setLightText(arg0);
                if(movePattern==MOVE_QUICK){
                    LinearLayout.LayoutParams layoutParams = (LayoutParams) iv.getLayoutParams();
                    layoutParams.leftMargin = (int) (item_width * arg0);
                    iv.setLayoutParams(layoutParams);
                }else if(movePattern==MOVE_DELAY) {
                    AnimationSet set=new AnimationSet(true);
                    TranslateAnimation animation=new TranslateAnimation(nowPosition*item_width, arg0*item_width, 0, 0);
                    set.addAnimation(animation);
                    set.setFillAfter(true);
                    set.setDuration(moveDuration);
                    iv.startAnimation(set);
                    nowPosition=arg0;
                }
                if (mListener != null)
                    mListener.onPageSelected(arg0);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
                if(movePattern==MOVE_SMOOTH){
                    LinearLayout.LayoutParams layoutParams = (LayoutParams) iv.getLayoutParams();
                    layoutParams.leftMargin = (int) (item_width * (arg0 + arg1));
                    iv.setLayoutParams(layoutParams);
                }
                if (mListener != null)
                    mListener.onPageScrolled(arg0, arg1, arg2);
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
                if (mListener != null)
                    mListener.onPageScrollStateChanged(arg0);
            }
        });
        return this;
    }

MOVE_QUICK和MOVE_SMOOTH的移送是设置了iv的左边间距,MOVE_DELAY则是使用了动画,AnimationSet会是动画结束后不会回到原处

    public interface VPListener {
        void onPageSelected(int arg0);

        void onPageScrolled(int arg0, float arg1, int arg2);

        void onPageScrollStateChanged(int arg0);
    }

    private void setLightText(int position) {
        // TODO Auto-generated method stub
        for (int i = 0; i < ll.getChildCount(); i++) {
            TextView tv = (TextView) ll.getChildAt(i);
            tv.setTextColor(textNormalColor);
            if (i == position)
                tv.setTextColor(textLightColor);
        }
    }

    public VPIndicator setVPListener(VPListener listener) {
        mListener = listener;
        return this;
    }

    public VPIndicator setIndicatorHeight(int dp) {
        iv_height = dp;
        return this;
    }

    public VPIndicator setVisible_item(int count) {
        visible_item = count;
        return this;
    }

    public VPIndicator setTextSize(float sp) {
        textSize = sp;
        return this;
    }

    public VPIndicator setTextNormalColor(int color) {
        textNormalColor = color;
        return this;
    }

    public VPIndicator setTextLightColor(int color) {
        textLightColor = color;
        return this;
    }

    public VPIndicator setIndicatorColor(int color) {
        ivColor = color;
        return this;
    }
    public VPIndicator setIndicatorUnder(boolean under) {
        iv_under = under;
        return this;
    }
    public VPIndicator setMovePattern(int pattern) {
        movePattern=pattern;
        return this;
    }
    public VPIndicator setMoveDuration(int duration) {
        moveDuration=duration;
        return this;
    }
    public VPIndicator setText(List<String> titles) {
        for (int i = 0; i < titles.size(); i++) {
            ll.addView(createTextView(titles.get(i)));
        }
        onTouchEvent();
        return this;
    }
    private TextView createTextView(String title) {
        // TODO Auto-generated method stub
        TextView textView = new TextView(context);
        textView.setText(title);
        textView.setGravity(Gravity.CENTER);
        LinearLayout.LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        textView.setLayoutParams(params);
        return textView;
    }

    private void onTouchEvent() {
        for (int i = 0; i < ll.getChildCount(); i++) {
            final int j = i;
            ll.getChildAt(i).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    mViewPager.setCurrentItem(j, false);
                }
            });
        }
    }

使用VPListener向外暴露ViewPager监听,setText(List titles)动态创建TextView,并设置了OnClickListener();

学习总结

onPageSelected(int arg0)当ViewPager页面确定发生变化时调用;
iv.setLayoutParams(layoutParams)执行时,父容器会执行onMeasure(),onLayout(),onDispatchDraw()方法;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值