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

实现签到规则如下:

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

实现步骤:

1.效果图2.自定义签到打卡View3.主程序逻辑处理4.主界面5.签到bean6.总结    

实现过程:
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知识及分享个人爱好文章: