Android自定義按周簽到打卡功能實(shí)例代碼
前言
之前實(shí)現(xiàn)過(guò)《Android可簽到的日歷控件》的功能,跟這篇一樣都是實(shí)現(xiàn)簽到打卡功能,這篇實(shí)現(xiàn)的是按月進(jìn)行打卡做標(biāo)識(shí),本篇內(nèi)容實(shí)現(xiàn)的按周進(jìn)行簽到打卡。
實(shí)現(xiàn)簽到規(guī)則如下:
1、連續(xù)簽到7天,即可獲得額外積分獎(jiǎng)勵(lì)。
2、連續(xù)簽到記錄在第8天開(kāi)始時(shí)將清零重新計(jì)算。
3、如果中斷簽到,連續(xù)簽到記錄也將清零。
實(shí)現(xiàn)步驟:
1.效果圖
2.自定義簽到打卡View
3.主程序邏輯處理
4.主界面
5.簽到bean
6.總結(jié)
實(shí)現(xiàn)過(guò)程:
1.效果圖

2.自定義簽到打卡View
/**
* description: 自定義簽到View.
*/
public class StepsView extends View {
/**
* 動(dòng)畫(huà)執(zhí)行的時(shí)間 230毫秒
*/
private final static int ANIMATION_TIME = 230;
/**
* 動(dòng)畫(huà)執(zhí)行的間隔次數(shù)
*/
private final static int ANIMATION_INTERVAL = 10;
/**
* 線段的高度
*/
private float mCompletedLineHeight = CalcUtils.dp2px(getContext(), 2f);
/**
* 圖標(biāo)寬度
*/
private float mIconWidth = CalcUtils.dp2px(getContext(), 21.5f);
/**
* 圖標(biāo)的高度
*/
private float mIconHeight = CalcUtils.dp2px(getContext(), 24f);
/**
* UP寬度
*/
private float mUpWidth = CalcUtils.dp2px(getContext(), 20.5f);
/**
* up的高度
*/
private float mUpHeight = CalcUtils.dp2px(getContext(), 12f);
/**
* 線段長(zhǎng)度
*/
private float mLineWidth = CalcUtils.dp2px(getContext(), 25f);
/**
* 已經(jīng)完成的圖標(biāo)
*/
private Drawable mCompleteIcon;
/**
* 正在進(jìn)行的圖標(biāo)
*/
private Drawable mAttentionIcon;
/**
* 默認(rèn)的圖標(biāo)
*/
private Drawable mDefaultIcon;
/**
* UP圖標(biāo)
*/
private Drawable mUpIcon;
/**
* 圖標(biāo)中心點(diǎn)Y
*/
private float mCenterY;
/**
* 線段的左上方的Y
*/
private float mLeftY;
/**
* 線段的右下方的Y
*/
private float mRightY;
/**
* 數(shù)據(jù)源
*/
private List<StepBean> mStepBeanList;
private int mStepNum = 0;
/**
* 圖標(biāo)中心點(diǎn)位置
*/
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);
/**
* 天數(shù)顏色
*/
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;
/**
* 是否執(zhí)行動(dòng)畫(huà)
*/
private boolean isAnimation = false;
/**
* 記錄重繪次數(shù)
*/
private int mCount = 0;
/**
* 執(zhí)行動(dòng)畫(huà)線段每次繪制的長(zhǎng)度,線段的總長(zhǎng)度除以總共執(zhí)行的時(shí)間乘以每次執(zhí)行的間隔時(shí)間
*/
private float mAnimationWidth = (mLineWidth / ANIMATION_TIME) * ANIMATION_INTERVAL;
/**
* 執(zhí)行動(dòng)畫(huà)的位置
*/
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<>();
//未完成文字畫(huà)筆
mUnCompletedPaint = new Paint();
mUnCompletedPaint.setAntiAlias(true);
mUnCompletedPaint.setColor(mUnCompletedLineColor);
mUnCompletedPaint.setStrokeWidth(2);
mUnCompletedPaint.setStyle(Paint.Style.FILL);
//已完成畫(huà)筆文字
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));
//已經(jīng)完成的icon
mCompleteIcon = ContextCompat.getDrawable(getContext(), R.drawable.sign);
//正在進(jìn)行的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() {
//圖標(biāo)的中中心Y點(diǎn)
mCenterY = CalcUtils.dp2px(getContext(), 28f) + mIconHeight / 2;
//獲取左上方Y(jié)的位置,獲取該點(diǎn)的意義是為了方便畫(huà)矩形左上的Y位置
mLeftY = mCenterY - (mCompletedLineHeight / 2);
//獲取右下方Y(jié)的位置,獲取該點(diǎn)的意義是為了方便畫(huà)矩形右下的Y位置
mRightY = mCenterY + mCompletedLineHeight / 2;
//計(jì)算圖標(biāo)中心點(diǎn)
mCircleCenterPointPositionList.clear();
//第一個(gè)點(diǎn)距離父控件左邊14.5dp
float size = mIconWidth / 2 + CalcUtils.dp2px(getContext(), 23f);
mCircleCenterPointPositionList.add(size);
for (int i = 1; i < mStepNum; i++) {
//從第二個(gè)點(diǎn)開(kāi)始,每個(gè)點(diǎn)距離上一個(gè)點(diǎn)為圖標(biāo)的寬度加上線段的23dp的長(zhǎng)度
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);
}
}
}
/**
* 繪制簽到(伴隨簽到動(dòng)畫(huà))
*/
@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) {
//下一個(gè)是已完成,當(dāng)前才需要繪制
canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
mRightY, mCompletedPaint);
} else {
//其余繪制灰色
//當(dāng)前位置執(zhí)行動(dòng)畫(huà)
if (i == mPosition - 1) {
//綠色開(kāi)始繪制的地方,
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);
}
}
}
//繪制圖標(biāo)
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) {
//當(dāng)前需要繪制
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);
}
}
//繪制圖標(biāo)
if (stepsBean.getState() == StepBean.STEP_COMPLETED || (i == mPosition
&& mCount == ANIMATION_TIME)) {
//已經(jīng)完成了或者是當(dāng)前動(dòng)畫(huà)完成并且需要當(dāng)前位置需要改變
if (stepsBean.getNumber() != 0) {
//是up的需要橙色
mTextNumberPaint.setColor(mCurrentTextColor);
} else {
//普通完成的顏色
mTextNumberPaint.setColor(mCompletedLineColor);
}
} else {
//還沒(méi)簽到的,顏色均為灰色
mTextNumberPaint.setColor(mUnCompletedLineColor);
}
//繪制UP
if (stepsBean.getNumber() != 0) {
//需要UP才進(jìn)行繪制
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);
}
//天數(shù)文字
canvas.drawText(stepsBean.getDay(),
currentComplectedXPosition - CalcUtils.dp2px(getContext(), 12f),
mCenterY + CalcUtils.dp2px(getContext(), 30f),
mTextDayPaint);
}
//記錄重繪次數(shù)
mCount = mCount + ANIMATION_INTERVAL;
if (mCount <= ANIMATION_TIME) {
//引起重繪
postInvalidate();
} else {
//重繪完成
isAnimation = false;
mCount = 0;
}
}
/**
* 繪制初始狀態(tài)的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) {
//下一個(gè)是已完成,當(dāng)前才需要繪制
canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
mRightY, mCompletedPaint);
} else {
//其余繪制灰色
canvas.drawRect(preComplectedXPosition, mLeftY, preComplectedXPosition + mLineWidth,
mRightY, mUnCompletedPaint);
}
}
//繪制圖標(biāo)
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);
}
//繪制增加的分?jǐn)?shù)數(shù)目
if (stepsBean.getState() == StepBean.STEP_COMPLETED) {
//已經(jīng)完成了
if (stepsBean.getNumber() != 0) {
//是up的需要橙色
mTextNumberPaint.setColor(mCurrentTextColor);
} else {
//普通完成的顏色
mTextNumberPaint.setColor(mCompletedLineColor);
}
} else {
//還沒(méi)簽到的,顏色均為灰色
mTextNumberPaint.setColor(mUnCompletedLineColor);
}
//繪制UP
if (stepsBean.getNumber() != 0) {
//需要UP才進(jìn)行繪制
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);
}
//天數(shù)文字
canvas.drawText(stepsBean.getDay(),
currentComplectedXPosition - CalcUtils.dp2px(getContext(), 12f),
mCenterY + CalcUtils.dp2px(getContext(), 30f),
mTextDayPaint);
}
}
/**
* 設(shè)置流程步數(shù)
*
* @param stepsBeanList 流程步數(shù)
*/
public void setStepNum(List<StepBean> stepsBeanList) {
if (stepsBeanList == null && stepsBeanList.size() == 0) {
return;
}
mStepBeanList = stepsBeanList;
mStepNum = mStepBeanList.size();
setChange();//重新繪制
//引起重繪
postInvalidate();
}
/**
* 執(zhí)行簽到動(dòng)畫(huà)
*
* @param position 執(zhí)行的位置
*/
public void startSignAnimation(int position) {
//線條從灰色變?yōu)榫G色
isAnimation = true;
mPosition = position;
//引起重繪
postInvalidate();
}
}
3.主程序邏輯處理
/**
* 一周簽到規(guī)則:
* 1、連續(xù)簽到7天,即可額外獲得15積分獎(jiǎng)勵(lì)
* 2、連續(xù)簽到記錄在第8天開(kāi)始時(shí)將清零重新計(jì)算
* 3、如果中斷簽到,連續(xù)簽到記錄也將清零
*
* 注:可以顯示簽到的動(dòng)畫(huà),這里沒(méi)有使用動(dòng)畫(huà)
* 需要?jiǎng)赢?huà)可以調(diào)用mStepView.startSignAnimation(int position)
* position表示需要做動(dòng)畫(huà)的位置
*/
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) {
//點(diǎn)擊簽到按鈕,請(qǐng)求后臺(tái)接口數(shù)據(jù)
//模擬請(qǐng)求接口數(shù)據(jù)成功
requestSuccessData();
}
});
}
/**
* 模擬請(qǐng)求接口數(shù)據(jù)成功后更新數(shù)據(jù)
*/
private void requestSuccessData() {
mStepBeans.clear();//清空初始化數(shù)據(jù)
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" +
"}";
//解析后臺(tái)請(qǐng)求數(shù)據(jù)
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("連續(xù)" + 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() {
//初始化模擬請(qǐng)求后臺(tái)數(shù)據(jù)
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" +
"}";
//解析后臺(tái)請(qǐng)求數(shù)據(jù)
SignListReq signListReq = new Gson().fromJson(reponse, SignListReq.class);
if (signListReq.getRet() == 0) {
setSignData(signListReq.getDatas());
}
}
/**
* 數(shù)據(jù)處理
*
* @param datas
*/
private void setSignData(SignListReq.DatasBean datas) {
//處理已簽到的數(shù)據(jù)
//先添加已簽到的日期到集合中
if (datas.getUserSingninList().size() != 0) {
for (int i = 0; i < datas.getUserSingninList().size(); i++) {
//時(shí)間格式: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];//日
//判斷是否需要顯示積分圖標(biāo),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));
}
}
}
//添加未簽到的數(shù)據(jù),填充為最近一周數(shù)據(jù)
if (mStepBeans.size() < 7) {
//獲取當(dāng)前時(shí)間的月日
Calendar now = Calendar.getInstance();
int currentMonth = now.get(Calendar.MONTH) + 1;//當(dāng)月
int currentDay = now.get(Calendar.DAY_OF_MONTH);//當(dāng)天
String currentTime = setData(currentMonth) + "." + setData(currentDay);
//后臺(tái)有簽到集合數(shù)據(jù)
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;
//判斷累積的天數(shù)是否超過(guò)當(dāng)月的總天數(shù)
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 {//后臺(tái)沒(méi)有簽到集合數(shù)據(jù),沒(méi)有的話從當(dāng)天時(shí)間開(kāi)始添加未來(lái)一周的日期數(shù)據(jù)
for (int i = 0; i < 7; i++) {
int parseInt = currentDay + i;
//判斷累積的天數(shù)是否超過(guò)當(dāng)月的總天數(shù)
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);
}
/**
* 獲取最大天數(shù)
*
* @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="連續(xù)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;
/**
* 正在進(jìn)行
*/
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.總結(jié)
該篇的功能是根據(jù)需求進(jìn)行功能的處理,自定義View是實(shí)現(xiàn)了簽到時(shí)的動(dòng)畫(huà)效果的,不過(guò)我們的需求不需要?jiǎng)赢?huà),所以這里就沒(méi)調(diào)用演示,需要的可以自行調(diào)用
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
詳解flutter中常用的container layout實(shí)例
這篇文章主要為大家介紹了詳解flutter中常用的container layout實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
RxJava和Retrofit2的統(tǒng)一處理單個(gè)請(qǐng)求示例詳解
這篇文章主要給大家介紹了關(guān)于RxJava和Retrofit2的統(tǒng)一處理單個(gè)請(qǐng)求的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
Android開(kāi)發(fā)中Activity的生命周期及加載模式詳解
這篇文章主要介紹了Android開(kāi)發(fā)中Activity的生命周期及加載模式詳解的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-05-05
Android開(kāi)發(fā)自定義TextView省略號(hào)樣式的方法
這篇文章主要介紹了Android開(kāi)發(fā)自定義TextView省略號(hào)樣式的方法,結(jié)合實(shí)例形式分析了Android文本控件TextView相關(guān)屬性與字符串操作技巧,需要的朋友可以參考下2017-10-10
Android JNI 調(diào)用時(shí)緩存字段和方法ID示例
這篇文章主要介紹了Android JNI 調(diào)用時(shí)緩存字段和方法ID示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Android如何實(shí)現(xiàn)動(dòng)態(tài)滾動(dòng)波形圖(心電圖)功能
這篇文章主要介紹了Android如何實(shí)現(xiàn)動(dòng)態(tài)滾動(dòng)波形圖(心電圖)功能,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03
Android仿微信列表滑動(dòng)刪除之可滑動(dòng)控件(一)
這篇文章主要為大家詳細(xì)介紹了Android仿微信列表滑動(dòng)刪除之可滑動(dòng)控件,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
Android 手勢(shì) 正則匹配圖片實(shí)例代碼
這篇文章主要介紹了Android 手勢(shì) 正則匹配圖片實(shí)例代碼,需要的朋友可以參考下2017-07-07
Android 自定義ProgressDialog進(jìn)度條對(duì)話框用法詳解
ProgressDialog為進(jìn)度對(duì)話框。android手機(jī)自帶的對(duì)話框顯得比較單一,我們可以通過(guò)ProgressDialog來(lái)自己定義對(duì)話框中將要顯示出什么東西2016-01-01

