Android自定义实现按周签到打卡功能

作者: 龙旋之谷 | 来源:发表于2019-06-03 09:15 被阅读38次

    之前实现过《Android可签到的日历控件》的功能,跟这篇一样都是实现签到打卡功能,这篇实现的是按月进行打卡做标识,本篇内容实现的按周进行签到打卡。

    实现签到规则如下:

    • 1、连续签到7天,即可获得额外积分奖励。
    • 2、连续签到记录在第8天开始时将清零重新计算。
    • 3、如果中断签到,连续签到记录也将清零。

    实现步骤:
    1.效果图
    2.自定义签到打卡View
    3.主程序逻辑处理
    4.主界面
    5.签到bean
    6.总结

    实现过程:
    1.效果图


    在这里插入图片描述

    2.自定义签到打卡View

    /**
     * description: 自定义签到View.
     */
    public class StepsView extends View {
    
        /**
         * 动画执行的时间 230毫秒
         */
        private final static int ANIMATION_TIME = 230;
        /**
         * 动画执行的间隔次数
         */
        private final static int ANIMATION_INTERVAL = 10;
    
        /**
         * 线段的高度
         */
        private float mCompletedLineHeight = CalcUtils.dp2px(getContext(), 2f);
    
        /**
         * 图标宽度
         */
        private float mIconWidth = CalcUtils.dp2px(getContext(), 21.5f);
        /**
         * 图标的高度
         */
        private float mIconHeight = CalcUtils.dp2px(getContext(), 24f);
        /**
         * UP宽度
         */
        private float mUpWidth = CalcUtils.dp2px(getContext(), 20.5f);
        /**
         * up的高度
         */
        private float mUpHeight = CalcUtils.dp2px(getContext(), 12f);
    
        /**
         * 线段长度
         */
        private float mLineWidth = CalcUtils.dp2px(getContext(), 25f);
    
        /**
         * 已经完成的图标
         */
        private Drawable mCompleteIcon;
        /**
         * 正在进行的图标
         */
        private Drawable mAttentionIcon;
        /**
         * 默认的图标
         */
        private Drawable mDefaultIcon;
        /**
         * UP图标
         */
        private Drawable mUpIcon;
        /**
         * 图标中心点Y
         */
        private float mCenterY;
        /**
         * 线段的左上方的Y
         */
        private float mLeftY;
        /**
         * 线段的右下方的Y
         */
        private float mRightY;
    
        /**
         * 数据源
         */
        private List<StepBean> mStepBeanList;
        private int mStepNum = 0;
    
        /**
         * 图标中心点位置
         */
        private List<Float> mCircleCenterPointPositionList;
        /**
         * 未完成的线段Paint
         */
        private Paint mUnCompletedPaint;
        /**
         * 完成的线段paint
         */
        private Paint mCompletedPaint;
        /**
         * 未完成颜色
         */
        private int mUnCompletedLineColor = ContextCompat.getColor(getContext(), R.color.c_d5a872);
        /**
         * 积分颜色
         */
        private int mUnCompletedTextColor = ContextCompat.getColor(getContext(), R.color.c_cccccc);
    
        /**
         * 天数颜色
         */
        private int mUnCompletedDayTextColor = ContextCompat.getColor(getContext(), R.color.c_736657);
    
        /**
         * up魅力值颜色
         */
        private int mCurrentTextColor = ContextCompat.getColor(getContext(), R.color.c_white);
        /**
         * 完成的颜色
         */
        private int mCompletedLineColor = ContextCompat.getColor(getContext(), R.color.c_d5a872);
    
        private Paint mTextNumberPaint;
    
    
        private Paint mTextDayPaint;
    
        /**
         * 是否执行动画
         */
        private boolean isAnimation = false;
    
        /**
         * 记录重绘次数
         */
        private int mCount = 0;
    
        /**
         * 执行动画线段每次绘制的长度,线段的总长度除以总共执行的时间乘以每次执行的间隔时间
         */
        private float mAnimationWidth = (mLineWidth / ANIMATION_TIME) * ANIMATION_INTERVAL;
    
        /**
         * 执行动画的位置
         */
        private int mPosition;
        private int[] mMax;
    
        public StepsView(Context context) {
            this(context, null);
        }
    
        public StepsView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public StepsView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        /**
         * init
         */
        private void init() {
            mStepBeanList = new ArrayList<>();
    
            mCircleCenterPointPositionList = new ArrayList<>();
    
            //未完成文字画笔
            mUnCompletedPaint = new Paint();
            mUnCompletedPaint.setAntiAlias(true);
            mUnCompletedPaint.setColor(mUnCompletedLineColor);
            mUnCompletedPaint.setStrokeWidth(2);
            mUnCompletedPaint.setStyle(Paint.Style.FILL);
    
            //已完成画笔文字
            mCompletedPaint = new Paint();
            mCompletedPaint.setAntiAlias(true);
            mCompletedPaint.setColor(mCompletedLineColor);
            mCompletedPaint.setStrokeWidth(2);
            mCompletedPaint.setStyle(Paint.Style.FILL);
    
            //number paint
            mTextNumberPaint = new Paint();
            mTextNumberPaint.setAntiAlias(true);
            mTextNumberPaint.setColor(mUnCompletedTextColor);
            mTextNumberPaint.setStyle(Paint.Style.FILL);
            mTextNumberPaint.setTextSize(CalcUtils.sp2px(getContext(), 10f));
    
            //number paint
            mTextDayPaint = new Paint();
            mTextDayPaint.setAntiAlias(true);
            mTextDayPaint.setColor(mUnCompletedDayTextColor);
            mTextDayPaint.setStyle(Paint.Style.FILL);
            mTextDayPaint.setTextSize(CalcUtils.sp2px(getContext(), 12f));
    
            //已经完成的icon
            mCompleteIcon = ContextCompat.getDrawable(getContext(), R.drawable.sign);
            //正在进行的icon
            mAttentionIcon = ContextCompat.getDrawable(getContext(), R.drawable.unsign);
            //未完成的icon
            mDefaultIcon = ContextCompat.getDrawable(getContext(), R.drawable.unsign);
            //UP的icon
            mUpIcon = ContextCompat.getDrawable(getContext(), R.drawable.jifendikuai);
        }
    
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            setChange();
        }
    
        private void setChange() {
            //图标的中中心Y点
            mCenterY = CalcUtils.dp2px(getContext(), 28f) + mIconHeight / 2;
            //获取左上方Y的位置,获取该点的意义是为了方便画矩形左上的Y位置
            mLeftY = mCenterY - (mCompletedLineHeight / 2);
            //获取右下方Y的位置,获取该点的意义是为了方便画矩形右下的Y位置
            mRightY = mCenterY + mCompletedLineHeight / 2;
    
            //计算图标中心点
            mCircleCenterPointPositionList.clear();
            //第一个点距离父控件左边14.5dp
            float size = mIconWidth / 2 + CalcUtils.dp2px(getContext(), 23f);
            mCircleCenterPointPositionList.add(size);
    
            for (int i = 1; i < mStepNum; i++) {
                //从第二个点开始,每个点距离上一个点为图标的宽度加上线段的23dp的长度
                size = size + mIconWidth + mLineWidth;
                mCircleCenterPointPositionList.add(size);
            }
        }
    
        @SuppressLint("DrawAllocation")
        @Override
        protected synchronized void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            if (mStepBeanList.size() != 0) {
                if (isAnimation) {
                    drawSign(canvas);
                } else {
                    drawUnSign(canvas);
                }
            }
        }
    
        /**
         * 绘制签到(伴随签到动画)
         */
        @SuppressLint("DrawAllocation")
        private void drawSign(Canvas canvas) {
            for (int i = 0; i < mCircleCenterPointPositionList.size(); i++) {
                //绘制线段
                float preComplectedXPosition = mCircleCenterPointPositionList.get(i) + mIconWidth / 2;
                if (i != mCircleCenterPointPositionList.size() - 1) {
                    //最后一条不需要绘制
                    if (mStepBeanList.get(i + 1).getState() == StepBean.STEP_COMPLETED) {
                        //下一个是已完成,当前才需要绘制
                        canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
                                mRightY, mCompletedPaint);
                    } else {
                        //其余绘制灰色
    
                        //当前位置执行动画
                        if (i == mPosition - 1) {
                            //绿色开始绘制的地方,
                            float endX = preComplectedXPosition + mAnimationWidth * (mCount / ANIMATION_INTERVAL);
                            //绘制
                            canvas.drawRect(preComplectedXPosition, mLeftY, endX, mRightY, mCompletedPaint);
                            //绘制
                            canvas.drawRect(endX, mLeftY, preComplectedXPosition + mLineWidth,
                                    mRightY, mUnCompletedPaint);
                        } else {
                            canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
                                    mRightY, mUnCompletedPaint);
                        }
                    }
                }
    
                //绘制图标
                float currentComplectedXPosition = mCircleCenterPointPositionList.get(i);
                Rect rect = new Rect((int) (currentComplectedXPosition - mIconWidth / 2),
                        (int) (mCenterY - mIconHeight / 2),
                        (int) (currentComplectedXPosition + mIconWidth / 2),
                        (int) (mCenterY + mIconHeight / 2));
    
                StepBean stepsBean = mStepBeanList.get(i);
    
                if (i == mPosition && mCount == ANIMATION_TIME) {
                    //当前需要绘制
                    mCompleteIcon.setBounds(rect);
                    mCompleteIcon.draw(canvas);
                } else {
                    if (stepsBean.getState() == StepBean.STEP_UNDO) {
                        mDefaultIcon.setBounds(rect);
                        mDefaultIcon.draw(canvas);
                    } else if (stepsBean.getState() == StepBean.STEP_CURRENT) {
                        mAttentionIcon.setBounds(rect);
                        mAttentionIcon.draw(canvas);
                    } else if (stepsBean.getState() == StepBean.STEP_COMPLETED) {
                        mCompleteIcon.setBounds(rect);
                        mCompleteIcon.draw(canvas);
                    }
                }
    
                //绘制图标
                if (stepsBean.getState() == StepBean.STEP_COMPLETED || (i == mPosition
                        && mCount == ANIMATION_TIME)) {
                    //已经完成了或者是当前动画完成并且需要当前位置需要改变
                    if (stepsBean.getNumber() != 0) {
                        //是up的需要橙色
                        mTextNumberPaint.setColor(mCurrentTextColor);
                    } else {
                        //普通完成的颜色
                        mTextNumberPaint.setColor(mCompletedLineColor);
                    }
                } else {
                    //还没签到的,颜色均为灰色
                    mTextNumberPaint.setColor(mUnCompletedLineColor);
                }
    
                //绘制UP
                if (stepsBean.getNumber() != 0) {
                    //需要UP才进行绘制
                    Rect rectUp =
                            new Rect((int) (currentComplectedXPosition - mUpWidth / 2),
                                    (int) (mCenterY - mIconHeight / 2 - CalcUtils.dp2px(getContext(), 8f) - mUpHeight),
                                    (int) (currentComplectedXPosition + mUpWidth / 2),
                                    (int) (mCenterY - mIconHeight / 2 - CalcUtils.dp2px(getContext(), 1f)));
                    mUpIcon.setBounds(rectUp);
                    mUpIcon.draw(canvas);
                }
    
                //0表示不需要显示积分,非0表示需要消失积分
                if (stepsBean.getNumber() != 0) {
                    canvas.drawText("+" + stepsBean.getNumber(),
                            currentComplectedXPosition - CalcUtils.dp2px(getContext(), 8f),
                            mCenterY / 2 - CalcUtils.dp2px(getContext(), 0.5f),
                            mTextNumberPaint);
                }
                //天数文字
                canvas.drawText(stepsBean.getDay(),
                        currentComplectedXPosition - CalcUtils.dp2px(getContext(), 12f),
                        mCenterY + CalcUtils.dp2px(getContext(), 30f),
                        mTextDayPaint);
            }
    
            //记录重绘次数
            mCount = mCount + ANIMATION_INTERVAL;
            if (mCount <= ANIMATION_TIME) {
                //引起重绘
                postInvalidate();
            } else {
                //重绘完成
                isAnimation = false;
                mCount = 0;
            }
        }
    
        /**
         * 绘制初始状态的view
         */
        @SuppressLint("DrawAllocation")
        private void drawUnSign(Canvas canvas) {
    
            for (int i = 0; i < mCircleCenterPointPositionList.size(); i++) {
                //绘制线段
                float preComplectedXPosition = mCircleCenterPointPositionList.get(i) + mIconWidth / 2;
                if (i != mCircleCenterPointPositionList.size() - 1) {
                    //最后一条不需要绘制
                    if (mStepBeanList.get(i + 1).getState() == StepBean.STEP_COMPLETED) {
                        //下一个是已完成,当前才需要绘制
                        canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
                                mRightY, mCompletedPaint);
                    } else {
                        //其余绘制灰色
                        canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
                                mRightY, mUnCompletedPaint);
                    }
                }
    
                //绘制图标
                float currentComplectedXPosition = mCircleCenterPointPositionList.get(i);
                Rect rect = new Rect((int) (currentComplectedXPosition - mIconWidth / 2),
                        (int) (mCenterY - mIconHeight / 2),
                        (int) (currentComplectedXPosition + mIconWidth / 2),
                        (int) (mCenterY + mIconHeight / 2));
    
    
                StepBean stepsBean = mStepBeanList.get(i);
    
                if (stepsBean.getState() == StepBean.STEP_UNDO) {
                    mDefaultIcon.setBounds(rect);
                    mDefaultIcon.draw(canvas);
                } else if (stepsBean.getState() == StepBean.STEP_CURRENT) {
                    mAttentionIcon.setBounds(rect);
                    mAttentionIcon.draw(canvas);
                } else if (stepsBean.getState() == StepBean.STEP_COMPLETED) {
                    mCompleteIcon.setBounds(rect);
                    mCompleteIcon.draw(canvas);
                }
    
                //绘制增加的分数数目
                if (stepsBean.getState() == StepBean.STEP_COMPLETED) {
                    //已经完成了
                    if (stepsBean.getNumber() != 0) {
                        //是up的需要橙色
                        mTextNumberPaint.setColor(mCurrentTextColor);
                    } else {
                        //普通完成的颜色
                        mTextNumberPaint.setColor(mCompletedLineColor);
                    }
                } else {
                    //还没签到的,颜色均为灰色
                    mTextNumberPaint.setColor(mUnCompletedLineColor);
                }
    
                //绘制UP
                if (stepsBean.getNumber() != 0) {
                    //需要UP才进行绘制
                    Rect rectUp =
                            new Rect((int) (currentComplectedXPosition - mUpWidth / 2),
                                    (int) (mCenterY - mIconHeight / 2 - CalcUtils.dp2px(getContext(), 8f) - mUpHeight),
                                    (int) (currentComplectedXPosition + mUpWidth / 2),
                                    (int) (mCenterY - mIconHeight / 2 - CalcUtils.dp2px(getContext(), 1f)));
                    mUpIcon.setBounds(rectUp);
                    mUpIcon.draw(canvas);
                }
    
                //0表示不需要显示积分,非0表示需要消失积分
                if (stepsBean.getNumber() != 0) {
                    //积分文字
                    canvas.drawText("+" + stepsBean.getNumber(),
                            currentComplectedXPosition - CalcUtils.dp2px(getContext(), 8f),
                            mCenterY / 2 - CalcUtils.dp2px(getContext(), 0.5f),
                            mTextNumberPaint);
                }
    
    
                //天数文字
                canvas.drawText(stepsBean.getDay(),
                        currentComplectedXPosition - CalcUtils.dp2px(getContext(), 12f),
                        mCenterY + CalcUtils.dp2px(getContext(), 30f),
                        mTextDayPaint);
            }
        }
    
        /**
         * 设置流程步数
         *
         * @param stepsBeanList 流程步数
         */
        public void setStepNum(List<StepBean> stepsBeanList) {
    
            if (stepsBeanList == null && stepsBeanList.size() == 0) {
                return;
            }
            mStepBeanList = stepsBeanList;
            mStepNum = mStepBeanList.size();
            setChange();//重新绘制
    
            //引起重绘
            postInvalidate();
        }
    
        /**
         * 执行签到动画
         *
         * @param position 执行的位置
         */
        public void startSignAnimation(int position) {
            //线条从灰色变为绿色
            isAnimation = true;
            mPosition = position;
            //引起重绘
            postInvalidate();
        }
    }
    

    3.主程序逻辑处理

    /**
     * 一周签到规则:
     * 1、连续签到7天,即可额外获得15积分奖励
     * 2、连续签到记录在第8天开始时将清零重新计算
     * 3、如果中断签到,连续签到记录也将清零
     *
     * 注:可以显示签到的动画,这里没有使用动画
     * 需要动画可以调用mStepView.startSignAnimation(int position)
     * position表示需要做动画的位置
     */
    public class MainActivity extends AppCompatActivity {
    
        private StepsView mStepView;
        private RelativeLayout rl_oval;
        private TextView text_sign;
        private TextView text_lianxusign;
        private ArrayList<StepBean> mStepBeans = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initView();
    
            initData();
    
            initListener();
        }
    
        private void initListener() {
    
            rl_oval.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //点击签到按钮,请求后台接口数据
                    //模拟请求接口数据成功
                    requestSuccessData();
                }
            });
        }
    
        /**
         * 模拟请求接口数据成功后更新数据
         */
        private void requestSuccessData() {
            mStepBeans.clear();//清空初始化数据
            String reponse = "{\n" +
                    "    \"datas\": {\n" +
                    "        \"day\": 3,\n" +
                    "        \"myPoint\": 10890,\n" +
                    "        \"signLog\": {\n" +
                    "            \"content\": \"每日签到\",\n" +
                    "            \"createTime\": \"2019-05-29 09:42:05\",\n" +
                    "            \"familyId\": \"0\",\n" +
                    "            \"id\": \"951660\",\n" +
                    "            \"integral\": \"4\",\n" +
                    "            \"logType\": \"3\",\n" +
                    "            \"orderId\": \"0\",\n" +
                    "            \"type\": \"1\",\n" +
                    "            \"userId\": \"43431\"\n" +
                    "        },\n" +
                    "        \"signState\": true,\n" +
                    "        \"userSingninList\": [\n" +
                    "            {\n" +
                    "                \"createTime\": \"2019-05-27 18:04:15\",\n" +
                    "                \"day\": \"1\",\n" +
                    "                \"familyId\": \"0\",\n" +
                    "                \"id\": \"278904\",\n" +
                    "                \"seriesDay\": \"1\",\n" +
                    "                \"type\": \"0\",\n" +
                    "                \"userId\": \"43431\"\n" +
                    "            },\n" +
                    "            {\n" +
                    "                \"createTime\": \"2019-05-28 09:31:02\",\n" +
                    "                \"day\": \"2\",\n" +
                    "                \"familyId\": \"0\",\n" +
                    "                \"id\": \"278905\",\n" +
                    "                \"seriesDay\": \"2\",\n" +
                    "                \"type\": \"0\",\n" +
                    "                \"userId\": \"43431\"\n" +
                    "            },\n" +
                    "            {\n" +
                    "                \"createTime\": \"2019-05-29 09:42:05\",\n" +
                    "                \"day\": \"3\",\n" +
                    "                \"familyId\": \"0\",\n" +
                    "                \"id\": \"278907\",\n" +
                    "                \"seriesDay\": \"3\",\n" +
                    "                \"type\": \"0\",\n" +
                    "                \"userId\": \"43431\"\n" +
                    "            }\n" +
                    "        ]\n" +
                    "    },\n" +
                    "    \"msg\": \"success!\",\n" +
                    "    \"ret\": 0\n" +
                    "}";
    
            //解析后台请求数据
            SignListReq signListReq = new Gson().fromJson(reponse, SignListReq.class);
            if (signListReq.getRet() == 0) {
                rl_oval.setBackgroundResource(R.drawable.lianxusign_bg);
                text_sign.setText("已签到");
                text_lianxusign.setVisibility(View.VISIBLE);
                text_lianxusign.setText("连续" + signListReq.getDatas().getDay() + "天");
    
                setSignData(signListReq.getDatas());
            }
    
        }
    
        private void initView() {
            mStepView = findViewById(R.id.step_view);
            rl_oval = findViewById(R.id.rl_oval);
            text_sign = findViewById(R.id.text_sign);
            text_lianxusign = findViewById(R.id.text_lianxusign);
    
        }
    
        private void initData() {
    
            //初始化模拟请求后台数据
            String reponse = "{\n" +
                    "    \"datas\": {\n" +
                    "        \"day\": 2,\n" +
                    "        \"myPoint\": 10886,\n" +
                    "        \"signLog\": {\n" +
                    "            \"content\": \"每日签到\",\n" +
                    "            \"createTime\": \"2019-05-28 09:31:02\",\n" +
                    "            \"familyId\": \"0\",\n" +
                    "            \"id\": \"951656\",\n" +
                    "            \"integral\": \"9\",\n" +
                    "            \"logType\": \"3\",\n" +
                    "            \"orderId\": \"0\",\n" +
                    "            \"type\": \"1\",\n" +
                    "            \"userId\": \"43431\"\n" +
                    "        },\n" +
                    "        \"signState\": true,\n" +
                    "        \"userSingninList\": [\n" +
                    "            {\n" +
                    "                \"createTime\": \"2019-05-27 18:04:15\",\n" +
                    "                \"day\": \"1\",\n" +
                    "                \"familyId\": \"0\",\n" +
                    "                \"id\": \"278904\",\n" +
                    "                \"seriesDay\": \"1\",\n" +
                    "                \"type\": \"0\",\n" +
                    "                \"userId\": \"43431\"\n" +
                    "            },\n" +
                    "            {\n" +
                    "                \"createTime\": \"2019-05-28 09:31:02\",\n" +
                    "                \"day\": \"2\",\n" +
                    "                \"familyId\": \"0\",\n" +
                    "                \"id\": \"278905\",\n" +
                    "                \"seriesDay\": \"2\",\n" +
                    "                \"type\": \"0\",\n" +
                    "                \"userId\": \"43431\"\n" +
                    "            }\n" +
                    "        ]\n" +
                    "    },\n" +
                    "    \"msg\": \"success!\",\n" +
                    "    \"ret\": 0\n" +
                    "}";
    
            //解析后台请求数据
            SignListReq signListReq = new Gson().fromJson(reponse, SignListReq.class);
            if (signListReq.getRet() == 0) {
                setSignData(signListReq.getDatas());
            }
        }
    
        /**
         * 数据处理
         *
         * @param datas
         */
        private void setSignData(SignListReq.DatasBean datas) {
    
            //处理已签到的数据
            //先添加已签到的日期到集合中
            if (datas.getUserSingninList().size() != 0) {
                for (int i = 0; i < datas.getUserSingninList().size(); i++) {
                    //时间格式:2019-05-27 18:04:15
                    String createTime = datas.getUserSingninList().get(i).getCreateTime();
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date d1 = null;
                    try {
                        d1 = df.parse(createTime);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    String timeString = df.format(d1);
                    //获取日期的月、日
                    String[] timeList = timeString.split(" ");
                    String[] split = timeList[0].split("-");
                    String month = split[1];//月
                    String day = split[2];//日
    
                    //判断是否需要显示积分图标,number表示-- 0为不显示积分,非0为显示积分
                    if (datas.getSignLog() != null && datas.getUserSingninList().get(i).getCreateTime().equals(datas.getSignLog().getCreateTime())) {
                        mStepBeans.add(new StepBean(StepBean.STEP_COMPLETED, Integer.parseInt(datas.getSignLog().getIntegral()), month + "." + day));
                    } else {
                        mStepBeans.add(new StepBean(StepBean.STEP_COMPLETED, 0, month + "." + day));
                    }
                }
            }
    
            //添加未签到的数据,填充为最近一周数据
            if (mStepBeans.size() < 7) {
    
                //获取当前时间的月日
                Calendar now = Calendar.getInstance();
                int currentMonth = now.get(Calendar.MONTH) + 1;//当月
                int currentDay = now.get(Calendar.DAY_OF_MONTH);//当天
                String currentTime = setData(currentMonth) + "." + setData(currentDay);
    
                //后台有签到集合数据
                if (datas.getUserSingninList().size() != 0) {
                    String createTime = datas.getUserSingninList().get(datas.getUserSingninList().size() - 1).getCreateTime();
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date d1 = null;
                    try {
                        d1 = df.parse(createTime);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    String timeString = df.format(d1);
                    String[] timeList = timeString.split(" ");
                    String[] split = timeList[0].split("-");
                    String month = split[1];//月
                    String day = split[2];//日
    
                    for (int i = mStepBeans.size(); i < 7; i++) {
                        int parseInt = Integer.parseInt(day) + i - 1;
                        //判断累积的天数是否超过当月的总天数
                        if (parseInt <= getDayOfMonth()) {
                            String time = setData(Integer.parseInt(month)) + "." + setData(parseInt);
                            if (currentTime.equals(time)) {
                                mStepBeans.add(new StepBean(StepBean.STEP_CURRENT, 0, time));
                            } else {
                                mStepBeans.add(new StepBean(StepBean.STEP_UNDO, 0, time));
                            }
                        } else {
                            String time = setData((Integer.parseInt(month) + 1)) + "." + setData(parseInt - getDayOfMonth());
                            if (currentTime.equals(time)) {
                                mStepBeans.add(new StepBean(StepBean.STEP_CURRENT, 0, time));
                            } else {
                                mStepBeans.add(new StepBean(StepBean.STEP_UNDO, 0, time));
                            }
                        }
                    }
                } else {//后台没有签到集合数据,没有的话从当天时间开始添加未来一周的日期数据
                    for (int i = 0; i < 7; i++) {
                        int parseInt = currentDay + i;
                        //判断累积的天数是否超过当月的总天数
                        if (parseInt <= getDayOfMonth()) {
                            String time = setData(currentMonth) + "." + setData(parseInt);
                            if (currentTime.equals(time)) {
                                mStepBeans.add(new StepBean(StepBean.STEP_CURRENT, 0, time));
                            } else {
                                mStepBeans.add(new StepBean(StepBean.STEP_UNDO, 0, time));
                            }
                        } else {
                            String time = setData((currentMonth + 1)) + "." + setData(parseInt - getDayOfMonth());
                            if (currentTime.equals(time)) {
                                mStepBeans.add(new StepBean(StepBean.STEP_CURRENT, 0, time));
                            } else {
                                mStepBeans.add(new StepBean(StepBean.STEP_UNDO, 0, time));
                            }
                        }
                    }
                }
            }
    
            mStepView.setStepNum(mStepBeans);
        }
    
        /**
         * 获取最大天数
         *
         * @return
         */
        public int getDayOfMonth() {
            Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
            int day = aCalendar.getActualMaximum(Calendar.DATE);
            return day;
        }
    
        /**
         * 日月份处理
         *
         * @param day
         * @return
         */
        public String setData(int day) {
            String time = "";
            if (day < 10) {
                time = "0" + day;
            } else {
                time = "" + day;
            }
    
            return time;
        }
    }
    

    4.主界面布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.activity.MainActivity">
    
        <RelativeLayout
            android:id="@+id/rl_oval"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginTop="150dp"
            android:layout_centerHorizontal="true"
            android:background="@drawable/sign_bg">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/text_sign"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="签到"
                    android:textColor="#fff"
                    android:layout_gravity="center_horizontal"
                    android:textSize="16sp" />
    
                <TextView
                    android:id="@+id/text_lianxusign"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="连续3天"
                    android:textColor="#fff"
                    android:visibility="gone"
                    android:layout_gravity="center_horizontal"
                    android:textSize="12sp" />
            </LinearLayout>
        </RelativeLayout>
    
        <com.sorgs.stepview.ui.widget.StepsView
            android:id="@+id/step_view"
            android:layout_below="@id/rl_oval"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="15dp"
            android:layout_width="match_parent"
            android:layout_height="77dp" />
    </RelativeLayout>
    

    5.签到bean

    package com.sorgs.stepview.bean;
    
    /**
     * description: 签到bean.
     */
    public class StepBean {
        /**
         * 未完成
         */
        public static final int STEP_UNDO = -1;
        /**
         * 正在进行
         */
        public static final int STEP_CURRENT = 0;
        /**
         * 已完成
         */
        public static final int STEP_COMPLETED = 1;
    
        private int state;
        private int number;//0为不显示积分,非0为显示积分
        private String day;
    
        public StepBean(int state, int number, String day) {
            this.state = state;
            this.number = number;
            this.day = day;
        }
    
    
        public int getNumber() {
            return number;
        }
    
        public void setNumber(int number) {
            this.number = number;
        }
    
        public int getState() {
            return state;
        }
    
        public void setState(int state) {
            this.state = state;
        }
    
        public String getDay() {
            return day;
        }
    
        public void setDay(String day) {
            this.day = day;
        }
    }
    

    6.总结
    该篇的功能是根据需求进行功能的处理,自定义View是实现了签到时的动画效果的,不过我们的需求不需要动画,所以这里就没调用演示,需要的可以自行调用

    需要Demo源码的童鞋可以在底部的公众号回复:"StepView"即可获取。


    以下是个人公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识及分享个人爱好文章:


    在这里插入图片描述

    相关文章

      网友评论

        本文标题:Android自定义实现按周签到打卡功能

        本文链接:https://www.haomeiwen.com/subject/pvxqxctx.html