Android自定义按周签到打卡功能实例代码

作者:龙旋ly 时间:2023-08-06 18:45:49 

前言

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

实现签到规则如下:

1、连续签到7天,即可获得额外积分奖励。

2、连续签到记录在第8天开始时将清零重新计算。

3、如果中断签到,连续签到记录也将清零。

实现步骤:

1.效果图

2.自定义签到打卡View

3.主程序逻辑处理

4.主界面

5.签到bean

6.总结

实现过程:

1.效果图

Android自定义按周签到打卡功能实例代码

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是实现了签到时的动画效果的,不过我们的需求不需要动画,所以这里就没调用演示,需要的可以自行调用

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

来源:https://www.jianshu.com/p/fd899d78e686

标签:android,签到,打卡
0
投稿

猜你喜欢

  • C#实现输入10个数存入到数组中并求max和min及平均数的方法示例

    2023-11-30 05:58:54
  • Android 个人理财工具四:添加账单页面 下

    2021-09-05 00:43:59
  • Java实现简单通讯录管理系统

    2022-06-28 01:15:54
  • Eclipse插件大全 挑选最牛的TOP30(全)

    2023-06-29 09:34:50
  • 常用Maven库,镜像库及maven/gradle配置(小结)

    2023-11-20 23:44:00
  • Android 中Notification弹出通知实现代码

    2021-05-31 14:48:18
  • Intellij IDEA创建spring-boot项目的图文教程

    2022-06-15 01:09:59
  • Java使用ArrayList实现扑克牌的示例代码

    2021-10-29 15:17:17
  • 详解JAVA 弱引用

    2022-03-12 01:30:29
  • Android 安全加密:Https编程详解

    2023-11-08 06:58:51
  • Android 获取屏幕高度,标题高度,状态栏高度(实例代码)

    2022-10-17 15:49:37
  • SSH框架网上商城项目第23战之在线支付功能实现

    2023-04-22 22:49:19
  • Java设计模式之责任链模式的概念、实现以及netty中的责任链模式

    2022-05-28 00:24:12
  • Spring中的事务隔离级别和传播行为

    2022-07-21 18:18:24
  • java 如何给对象中的包装类设置默认值

    2022-02-09 21:04:08
  • Android图片三级缓存策略(网络、本地、内存缓存)

    2022-08-06 01:28:19
  • 浅谈关于Mybatis的mapper-locations配置问题

    2023-09-24 06:06:16
  • C#算法之回文数

    2022-06-26 20:02:38
  • Java中关键字synchronized的使用方法详解

    2022-04-14 06:18:54
  • Spring Boot实现图片上传功能

    2023-05-17 05:06:05
  • asp之家 软件编程 m.aspxhome.com