package com.example.dxy.myapplication.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Build;import android.os.Bundle;import android.os.Parcelable;import android.support.annotation.RequiresApi;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import com.example.dxy.myapplication.R;import java.util.ArrayList;public class IndicatorView extends View implements ViewPager.OnPageChangeListener {    //节点间距    private float mNodeGap;    //节点个数    private int mNodeCount;    //节点圆形半径    private float mNodeRadius;    //节点默认填充颜色    private int mNodeColor;    //移动节点填充颜色    private int mSelectedNodeColor;    //当前选中节点的索引    private int mCurrentIndex = 0;    //viewpager偏移量[0,1)    private float mCurrentPositionOffset = 0;    private ViewPager mViewPager;    private Paint mNodePaint = new Paint(Paint.ANTI_ALIAS_FLAG);    private Paint mSelectedNodePaint = new Paint(Paint.ANTI_ALIAS_FLAG);    private Context mContext;    public IndicatorView(Context context) {        this(context, null);    }    public IndicatorView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.mContext = context;        obtainAttributes(context, attrs);    }    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        this.mContext = context;        obtainAttributes(context, attrs);    }    private void obtainAttributes(Context context, AttributeSet attrs) {        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);        mNodeGap = ta.getDimension(R.styleable.IndicatorView_node_gap, dp2px(10));        mNodeColor = ta.getColor(R.styleable.IndicatorView_node_default_color, Color.parseColor("#FFFF00"));        mSelectedNodeColor = ta.getColor(R.styleable.IndicatorView_node_select_color, Color.parseColor("#FF0000"));        mNodeRadius = ta.getDimension(R.styleable.IndicatorView_node_radius, dp2px(5));        mNodePaint.setColor(mNodeColor);        mNodePaint.setStyle(Paint.Style.FILL);        mSelectedNodePaint.setColor(mSelectedNodeColor);        mSelectedNodePaint.setStyle(Paint.Style.FILL);        ta.recycle();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        if (mNodeCount <= 0) {            super.onMeasure(widthMeasureSpec, heightMeasureSpec);        } else {            final int measureWidth = (int) ((mNodeCount - 1) * mNodeGap + mNodeCount * 2 * mNodeRadius);            final int measureHeight = (int) (2 * mNodeRadius);            setMeasuredDimension(measureWidth, measureHeight);        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        for (int i = 0; i < mNodeCount; i++) {            canvas.drawCircle(mNodeRadius + i * mNodeGap + 2 * i * mNodeRadius, mNodeRadius, mNodeRadius, mNodePaint);        }        canvas.drawCircle(mNodeRadius + mCurrentIndex * mNodeGap + 2 * mCurrentIndex * mNodeRadius + (2 * mNodeRadius + mNodeGap) * mCurrentPositionOffset                , mNodeRadius, mNodeRadius, mSelectedNodePaint);    }    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        /**         * position:当前View的位置         * mCurrentPositionOffset:当前View的偏移量比例.[0,1)         */        this.mCurrentIndex = position;        this.mCurrentPositionOffset = positionOffset;        invalidate();    }    @Override    public void onPageSelected(int i) {        //会出现mCurrentPositionOffset!=0,这个方法调用        //加if判断防颤抖        if (mCurrentPositionOffset == 0) {            mCurrentIndex = i;            invalidate();        }           }    @Override    public void onPageScrollStateChanged(int i) {    }    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable("instanceState", super.onSaveInstanceState());        bundle.putInt("mCurrentTab", mCurrentIndex);        bundle.putInt("mNodeCount", mNodeCount);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (state instanceof Bundle) {            Bundle bundle = (Bundle) state;            mCurrentIndex = bundle.getInt("mCurrentTab");            mNodeCount = bundle.getInt("mNodeCount");            if (mCurrentIndex >= 0 && mCurrentIndex < mNodeCount) {                requestLayout();            }            state = bundle.getParcelable("instanceState");        }        super.onRestoreInstanceState(state);    }    /**     * 关联ViewPager,用于连适配器都不想自己实例化的情况     */    public void setViewPager(ViewPager vp, FragmentActivity fa, ArrayList fragments) {        setViewPager(vp, fa.getSupportFragmentManager(), fragments);    }    /**     * 关联ViewPager,用于连适配器都不想自己实例化的情况     */    public void setViewPager(ViewPager vp, FragmentManager fm, ArrayList fragments) {        if (vp == null) {            throw new IllegalStateException("ViewPager can not be NULL !");        }        this.mViewPager = vp;        this.mViewPager.setAdapter(new InnerPagerAdapter(fm, fragments));        this.mViewPager.removeOnPageChangeListener(this);        this.mViewPager.addOnPageChangeListener(this);        mNodeCount = fragments.size();        requestLayout();    }    static class InnerPagerAdapter extends FragmentPagerAdapter {        private ArrayList fragments = new ArrayList<>();        public InnerPagerAdapter(FragmentManager fm, ArrayList fragments) {            super(fm);            this.fragments = fragments;        }        @Override        public int getCount() {            return fragments.size();        }        @Override        public Fragment getItem(int position) {            return fragments.get(position);        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            // 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁            // super.destroyItem(container, position, object);        }        @Override        public int getItemPosition(Object object) {            return PagerAdapter.POSITION_NONE;        }    }    protected int dp2px(float dp) {        final float scale = mContext.getResources().getDisplayMetrics().density;        return (int) (dp * scale + 0.5f);    }    protected int sp2px(float sp) {        final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;        return (int) (sp * scale + 0.5f);    }}

 

更多相关文章

  1. 意见反馈 页面布局的设计
  2. ViewPager初步用法(二)
  3. Android(安卓)SAX解析XML文件
  4. android Studio listView 简单的用法
  5. 7.高级UI组件
  6. 过期Gallery取代方案horizontalscrollView之幻灯片效果
  7. 自动输入文本效果—AutoCompleteTextView
  8. 绘制直角坐标系
  9. android studio自动提示文本框

随机推荐

  1. 【前端】Promise的用法
  2. 【前端】es6的const定义的常量不能更改该
  3. 【前端】一道算法题,有会的可以一起讨论下
  4. 校园生活服务平台小程序系统具备哪些功能
  5. 服务器防火墙如何开放端口?常见的服务器端
  6. 使用函数封装一个动态表格,自行写5个系统
  7. foreach循环
  8. 1. 循环省市区 2. print_f打印其中一个
  9. 疯狂自定义函数(动态表格)
  10. 运算符以及函数的使用