• android 开发 View _16 自定义计步器View、自定义柱状图View


    /**
     *@content:实现计步的环形View
     *@time:2018-7-30
     *@build:
     */
    
    public class CountStepsAnnularView extends View {
        private final String TAG = "CountStepsAnnularView";
        //文字组
        private String mAimText;
        private float mAimNum;//目标步数
        private String mStepText;
        private float mCurrentNum;//当前步数
        //参数组
        private float mPadding;//内边距
        private float mOuterRaceWidth;//外环宽度
        private float mInnerRaceWidth;//内环宽度
        private Paint mPaint;
        private Path mPath;
        //颜色组
        private int mAimTextColor;
        private int mCurrenStepNumColor;
        private int mStepTextColor;
        private int[] mOuterRaceColors;
        private float [] mOuterRaceColorPositions;
        private int[] mInnerRaceColors;
        private float [] mInnerRaceColorsPositions;
    
        //动画变量值
        private int animation_innerRace;
        private int animation_currentStep;
        private boolean mStartAnimation;
    
    
        public CountStepsAnnularView(Context context) {
            super(context);
            init();
    
        }
    
        public CountStepsAnnularView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
    
        }
    
        public CountStepsAnnularView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
    
        }
        /**
         * 添加数据的方法
         * @param setAimText ”目标“的文字
         * @param setStepText “步” 的文字
         * @param setAimStepNum 目标步数
         * @param setCurrenStepNum 当前步数
         * @param aimTextColor 目标文字颜色
         * @param currenStepNumColor 当前步数文字颜色
         * @param stepTextColor 步的显示颜色
         * @param startAnimation 是否启用动画
         */
        public void setData(String setAimText,String setStepText,float setAimStepNum,float setCurrenStepNum,
                            int aimTextColor,int currenStepNumColor,int stepTextColor,boolean startAnimation){
            this.mAimText = setAimText;//设置目标文字
            this.mStepText = setStepText;//设置步文字animation_innerRace
            this.mAimNum = setAimStepNum;//设置目标步数
            this.mCurrentNum = setCurrenStepNum;//设置当前步数
            animation_innerRace = 0;
            animation_currentStep = 0 ;
            if(aimTextColor != 0){
                this.mAimTextColor = aimTextColor;
            }else {
                mAimTextColor = 0xF0111111;
            }
            if(currenStepNumColor != 0){
                this.mCurrenStepNumColor = currenStepNumColor;
            }else {
                mCurrenStepNumColor = 0xF0111111;
            }
            if(stepTextColor != 0){
                this.mStepTextColor = stepTextColor;
            }else {
                mStepTextColor = 0xF0111111;
            }
            this.mStartAnimation = startAnimation;
        }
    
        /**
         * 设置颜色的方法
         * @param outerRaceColors 外环颜色组 例如: int [] colors = new int[]{0xff56F9D0,0xFF4194F9};
         * @param outerRaceColorsPositions 外环颜色渐变点 例如: float [] floats = new float[]{0,0.5f};
         * @param innerRaceColors 内环颜色组
         * @param innerRaceColorspPositions 内环颜色渐变点
         * @ps 颜色组和渐变点组 数量需要一致
         */
        public void setGradientColors(int [] outerRaceColors,float [] outerRaceColorsPositions,
                                      int [] innerRaceColors,float[] innerRaceColorspPositions){
            this.mOuterRaceColors = outerRaceColors;
            this.mOuterRaceColorPositions = outerRaceColorsPositions;
            this.mInnerRaceColors = innerRaceColors;
            this.mInnerRaceColorsPositions = innerRaceColorspPositions;
    
        }
    
    
    
        private void init(){
            mPaint = new Paint();
            mPath = new Path();
    
        }
        private void initData(){
            mOuterRaceWidth = getWidth()/10;
            mPadding = mOuterRaceWidth/2+5;
            mInnerRaceWidth = mOuterRaceWidth - 3;
            if(mOuterRaceColors == null){
                mOuterRaceColors = new int[]{0xff56F9D0,0xFF4194F9};
                mOuterRaceColorPositions = new float[]{0,0.5f};
            }
            if(mInnerRaceColors == null){
                mInnerRaceColors = new int[]{0xFF8EF9BE,0xFF26FCB1};
                mInnerRaceColorsPositions = new float[]{0,0.5f};
            }
        }
    
        //画外环
        private void outerRace(Canvas canvas){
            mPaint.reset();
            mPath.reset();
            //setLayerType(LAYER_TYPE_SOFTWARE,null);//关闭硬件加速
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(mOuterRaceWidth);
            mPaint.setStyle(Paint.Style.STROKE);
            SweepGradient sg = new SweepGradient(getWidth()/2,getHeight()/2,mOuterRaceColors,mOuterRaceColorPositions);
            Matrix matrix = new Matrix();
            matrix.preRotate(135,getWidth(),getHeight());
            sg.setLocalMatrix(matrix);
            mPaint.setShader(sg);
            RectF rectF = new RectF();
            rectF.left = mPadding;
            rectF.top = mPadding;
            rectF.right = getWidth()-mPadding;
            rectF.bottom = getHeight()-mPadding;
            mPath.addArc(rectF,135,270);
            canvas.drawPath(mPath,mPaint);
        }
    
        //画内环
        private void innerRace(Canvas canvas){
            mPaint.reset();
            mPath.reset();
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(mInnerRaceWidth);
            mPaint.setStyle(Paint.Style.STROKE);
            SweepGradient sg = new SweepGradient(getWidth()/2,getHeight()/2,mInnerRaceColors,mInnerRaceColorsPositions);
            Matrix matrix = new Matrix();
            matrix.preRotate(135,getWidth(),getHeight());
            sg.setLocalMatrix(matrix);
            mPaint.setShader(sg);
            RectF rectF = new RectF();
            rectF.left = mPadding;
            rectF.top = mPadding;
            rectF.right = getWidth() - mPadding;
            rectF.bottom = getHeight() - mPadding ;
            float currentNum = (float) 270 * (mCurrentNum / mAimNum);
            if(mStartAnimation) {
                //270度是内环最大值,不可以超过270
                if (mCurrentNum > mAimNum) {
                    if(animation_innerRace < 270){
                        animation_innerRace = animation_innerRace + 5;
                    }
                    mPath.addArc(rectF, 135, animation_innerRace);
                } else {
    
                    if (animation_innerRace < currentNum) {
                        animation_innerRace = animation_innerRace + 5;
                    }
                    mPath.addArc(rectF, 135, animation_innerRace);
                }
            }else {
                //270度是内环最大值,不可以超过270
                if (mCurrentNum > mAimNum) {
                    mPath.addArc(rectF, 135, 270);
                } else {
                    mPath.addArc(rectF, 135, currentNum);
                }
            }
            canvas.drawPath(mPath,mPaint);
        }
    
        //目标文字
        private void titleText(Canvas canvas){
            mPath.reset();
            mPaint.reset();
            String aimNumText = Integer.toString((int)mAimNum);
            int num = aimNumText.length()+mAimText.length()+mStepText.length()+1;
            mPaint.setTextAlign(Paint.Align.CENTER);
            mPaint.setColor(mAimTextColor);
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(getWidth()/100);
            if(num < 10){
                mPaint.setTextSize(getWidth()/10);
            }else {
                mPaint.setTextSize(getWidth()/(num)+2);
            }
            float y = getHeight()/2 - mPadding ;
            float x = getWidth()/2;
            canvas.drawText(mAimText+" "+aimNumText+mStepText,x,y,mPaint);
    
        }
    
        //当前数字
        private void currentNumText(Canvas canvas){
            mPath.reset();
            mPaint.reset();
            mPaint.setTextAlign(Paint.Align.CENTER);
            mPaint.setColor(mCurrenStepNumColor);
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(getWidth()/100);
            mPaint.setTextSize(getWidth()/5);
            float y = getHeight()/2+getWidth()/10+mPadding;
            float x = getWidth()/2;
            if(mStartAnimation) {
                if (animation_currentStep < mCurrentNum) {
                    if (mCurrentNum < 300) {
                        animation_currentStep++;
                    } else {
                        if (animation_currentStep < mCurrentNum - 500) {
                            animation_currentStep = animation_currentStep + 300;
                        }else if(animation_currentStep < mCurrentNum - 301){
                            animation_currentStep = animation_currentStep + 50;
                        }else if(animation_currentStep < mCurrentNum -51){
                            animation_currentStep = animation_currentStep + 20;
                        }else if (animation_currentStep < mCurrentNum -11){
                            animation_currentStep = animation_currentStep + 5;
                        }else if (animation_currentStep < mCurrentNum){
                            animation_currentStep = animation_currentStep + 1;
                        }
                    }
                }
                canvas.drawText(Integer.toString((int) animation_currentStep), x, y, mPaint);
            }else {
                canvas.drawText(Integer.toString((int) mCurrentNum), x, y, mPaint);
            }
        }
    
        //步文字
        private void stepText(Canvas canvas){
            mPath.reset();
            mPaint.reset();
            mPaint.setTextAlign(Paint.Align.CENTER);
            mPaint.setColor(mStepTextColor);
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(getWidth()/100);
            mPaint.setTextSize(getWidth()/10);
            float y = getHeight()/2+getWidth()/10+getWidth()/5+5;
            float x = getWidth()/2;
            canvas.drawText(mStepText,x,y,mPaint);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            initData();
            outerRace(canvas);
            innerRace(canvas);
            titleText(canvas);
            currentNumText(canvas);
            stepText(canvas);
            postInvalidateDelayed(1);
    
        }
    }
     
    /**
     *@content:自定义柱状图View
     *@time:2018-7-31
     *@build:
     */
    
    public class BarGraphView extends View {
        private final String TAG = "BarGraphView";
        private List<Item> mItemList = new ArrayList<>();;
        private Paint mPaint;
        private Paint mPaintTiemText;
        private Paint mPaintCurrenNumText;
        private Path mPath;
        private Path mSrc;
        private float mWPadding;//宽边距 X边距
        private float mHPadding;//高边距 Y边距
        private float mSpacing;// item之间的间距
        private float mItemWidth; //item 的宽度
        private float mItemHeight; //item 的高度
        private float mItemNum; // item 的数量
        private float mBottomLine; //底线上的Y坐标值
        private float mMaxValue;
        //颜色组
        private int[] mItemColors ;
        private float[] mItemColorsPosition;
        private int mTiemTextColor;
        private int mCurrenNumTextColor;
    
    
        public BarGraphView(Context context) {
            super(context);
            initPaint();
        }
    
        public BarGraphView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initPaint();
        }
    
        public BarGraphView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initPaint();
        }
    
        /**
         * 添加数据的方法
         * @param item  例子:view.addData(new BarGraphView.Item("12-7",1651));
         */
        public void addData(Item item){
            mItemList.add(item);
            //计算添加到List中的最大值,并且给最大值增加2000上限
            mMaxValue = 0;
            if(!mItemList.isEmpty()) {
                for (int j = 0; j < mItemList.size(); j++) {
                    float numA = mItemList.get(j).currenNum;
                    if (mMaxValue < numA) {
                        mMaxValue = numA;
                    }
                }
                mMaxValue = mMaxValue + 2000;
            }
        }
    
        public List<Item> getData(){
            return mItemList;
    
        }
    
        /**
         * 设置颜色的方法
         * @param mItemColors 圆柱体的颜色组
         * @param mItemColorsPosition 圆柱体的颜色组渐变点
         * @param mTiemTextColor 时间text的颜色
         * @param mCurrenNumTextColor 步数text的颜色
         */
        public void setColors(int[] mItemColors,float[] mItemColorsPosition,int mTiemTextColor,int mCurrenNumTextColor){
            this.mItemColors = mItemColors;
            this.mItemColorsPosition = mItemColorsPosition;
            this.mTiemTextColor = mTiemTextColor;
            this.mCurrenNumTextColor = mCurrenNumTextColor;
        }
    
    
        private void initPaint(){
            this.mPaint = new Paint();
            this.mPaintTiemText = new Paint();
            this.mPaintCurrenNumText = new Paint();
            this.mPath = new Path();
            this.mSrc = new Path();
        }
        private void initData(){
            if(!mItemList.isEmpty()) {
                mItemNum = mItemList.size();
            }
            if(mItemColors == null){
                mItemColors = new int[]{0xFF2BF19E,0xFF1BE2FC};
            }
            if (mItemColorsPosition == null){
                mItemColorsPosition = new float[]{0.2f,0.8f};
            }
            if (mTiemTextColor == 0){
                mTiemTextColor = Color.BLACK;
            }
            if (mCurrenNumTextColor == 0){
                mCurrenNumTextColor = Color.BLACK;
            }
    
            mWPadding = getWidth()/20; //宽度内边距
            mHPadding = getHeight()/10; //高度内边距
            mItemWidth = getWidth()/(10+mItemNum);  //圆柱体的宽度
            mBottomLine = getHeight()-mHPadding*2; //底部横线坐标
            if(mItemList.size() == 1){
                //只有一个item时,处理圆柱间距
                mSpacing = getWidth()/2 - mItemWidth;
            }else if (mItemList.size() == 2) {
                //只有二个item时,处理圆柱间距
                mSpacing = getWidth() / 4;
            }else if (mItemList.size() == 3){
                //只有三个item时,处理圆柱间距
                mSpacing = getWidth() / 6;
            }else {
                mSpacing = ((getWidth() - mWPadding*2 - mItemWidth*mItemNum)/mItemNum)/1.15f; //圆柱体之间的间距
            }
    
    
        }
    
        /**
         * 画底部横线
         * @param canvas 画布
         */
        private void drawXline(Canvas canvas){
            mPaint.reset();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(Color.BLACK);
            mPaint.setStrokeWidth(2);
            int [] colors = new int[]{0xFF7E42FF,0xFF2BB5FA};
            float[] colorsPosition = new float[]{0.2f,0.6f};
            RadialGradient rg = new RadialGradient(getWidth()/2,
                    getHeight()-mHPadding*2,
                    getWidth(),
                    colors,colorsPosition,Shader.TileMode.CLAMP);
            mPaint.setShader(rg);
            canvas.drawLine(mWPadding,getHeight()-mHPadding*2,getWidth()-mWPadding,getHeight()-mHPadding*2,mPaint);
    
        }
    
        /**
         * 画圆柱 画日期 画数值
         * @param canvas 画布
         */
        private void drawItem(Canvas canvas){
            mPaint.reset();
            mPaintTiemText.reset();
            mPaintCurrenNumText.reset();
            mPath.reset();
            //柱状图画笔
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setStrokeWidth(5);
            mPaint.setColor(Color.BLUE);
            LinearGradient lg = new LinearGradient(0,getHeight(),getWidth(),0,mItemColors,mItemColorsPosition,Shader.TileMode.CLAMP);
            mPaint.setShader(lg);
            //日期画笔
            mPaintTiemText.setAntiAlias(true);
            mPaintTiemText.setStyle(Paint.Style.FILL);
            mPaintTiemText.setStrokeWidth(5);
            mPaintTiemText.setTextSize(getWidth()/35);
            mPaintTiemText.setTextAlign(Paint.Align.LEFT);
            mPaintTiemText.setColor(mTiemTextColor);
            //数值画笔
            mPaintCurrenNumText.setAntiAlias(true);
            mPaintCurrenNumText.setStyle(Paint.Style.FILL);
            mPaintCurrenNumText.setStrokeWidth(5);
            mPaintCurrenNumText.setTextSize(getWidth()/35);
            mPaintCurrenNumText.setTextAlign(Paint.Align.LEFT);
            mPaintCurrenNumText.setColor(mCurrenNumTextColor);
            mItemHeight = (getHeight() - mHPadding * 3) * (mItemList.get(0).currenNum / mMaxValue);
            if(!mItemList.isEmpty()) {
                //画第一个圆柱
                RectF rect = new RectF();
                rect.left = mWPadding + mSpacing;
                rect.top = mBottomLine - mItemHeight;
                rect.right = mWPadding + mSpacing + mItemWidth;
                rect.bottom = mBottomLine;
                mPath.addRect(rect, Path.Direction.CW);
                //画日期
                canvas.drawText(mItemList.get(0).time,
                        mWPadding + mSpacing,
                        mBottomLine + mHPadding,
                        mPaintTiemText);
                //画数值
                canvas.drawText(Integer.toString((int) (mItemList.get(0).currenNum)),
                        mWPadding + mSpacing,
                        mBottomLine - mItemHeight - 5,
                        mPaintCurrenNumText);
                //画剩下的圆柱
                    for (int i = 1; i < mItemList.size(); i++) {
                        Item item = mItemList.get(i);
                        mItemHeight = (getHeight() - mHPadding * 3) * (item.currenNum / mMaxValue);
                        RectF rectF = new RectF();
                        rectF.left = mWPadding + mSpacing * (i + 1) + mItemWidth * i;
                        rectF.top = mBottomLine - mItemHeight;
                        rectF.right = mWPadding + mSpacing * (i + 1) + mItemWidth * (i + 1);
                        rectF.bottom = mBottomLine;
                        mSrc = new Path();//画单个圆柱
                        mSrc.addRect(rectF, Path.Direction.CW);
                        mPath.addPath(mSrc);//将单个圆柱添加到mPath中
                        canvas.drawText(item.time,
                                mWPadding + mSpacing * (i + 1) + mItemWidth * i,
                                mBottomLine + mHPadding,
                                mPaintTiemText);//画日期
                        canvas.drawText(Integer.toString((int) (item.currenNum)),
                                mWPadding + mSpacing * (i + 1) + mItemWidth * i,
                                mBottomLine - mItemHeight - 5,
                                mPaintCurrenNumText);//画步数
                    }
                    canvas.drawPath(mPath, mPaint);//一次性添加全部圆柱
            }else {
                mPaintTiemText.setTextSize(getWidth()/20);
                canvas.drawText("无数据",getWidth()/2,getHeight()/2,mPaintTiemText);
            }
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            initData();
            drawXline(canvas);
            drawItem(canvas);
        }
    
         public static class Item {
            public String time;
            public float currenNum;
            public Item (String time,float currenNum){
                this.time = time;
                this.currenNum = currenNum;
            }
        }
    }
     
  • 相关阅读:
    poj 2000
    poj1316
    poj1922
    poj2017
    poj1833 排列
    poj1338
    poj2136
    poj2242
    IE兼容html5标签
    绑定事件后,某些情况下需要解绑该事件
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/9708588.html
Copyright © 2020-2023  润新知