上来就干,是我一贯的作风!

先预览下效果图

未签到效果.png

已签到效果.png

分析控件结构:

从上到下依次是TextView→GridView→GridView

布局代码:

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@android:color/white">

android:id="@+id/tvYear"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:padding="10dp"

android:text="2017年7月"

android:gravity="center"

android:textColor="@android:color/white"

android:background="@color/colorAccent"/>

android:id="@+id/gvWeek"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:numColumns="7">

android:id="@+id/gvDate"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:numColumns="7">

1、tvYear负责显示年月。

2、gvWeek负责显示星期几

3、gvDate负责显示日历

把整体布局作为组合控件封装在SignDate类里面,SignDate主要代码如下:

public class SignDate extends LinearLayout {

private TextView tvYear;

private InnerGridView gvWeek;

private InnerGridView gvDate;

private AdapterDate adapterDate;

public SignDate(Context context) {

super(context);

init();

}

...

private void init(){

View view = View.inflate(getContext(),R.layout.layout_signdate,this);

tvYear = view.findViewById(R.id.tvYear);

gvWeek = view.findViewById(R.id.gvWeek);

gvDate = view.findViewById(R.id.gvDate);

tvYear.setText(DateUtil.getCurrentYearAndMonth());

gvWeek.setAdapter(new AdapterWeek(getContext()));

adapterDate = new AdapterDate(getContext());

gvDate.setAdapter(adapterDate);

}

/**

* 签到成功的回调

* @param onSignedSuccess

*/

public void setOnSignedSuccess(OnSignedSuccess onSignedSuccess){

adapterDate.setOnSignedSuccess(onSignedSuccess);

}

}

代码中AdapterWeek就是简单的设置星期几数据,这里不多介绍。

在AdapterDate中实现了本月天数计算,开始天数应该显示在星期几的位置,和点击签到实现签到效果,代码如下:

public class AdapterDate extends BaseAdapter {

private Context context;

private List days = new ArrayList<>();

//日历数据

private List status = new ArrayList<>();

//签到状态,实际应用中初始化签到状态可通过该字段传递

private OnSignedSuccess onSignedSuccess;

//签到成功的回调方法,相应的可自行添加签到失败时的回调方法

public AdapterDate(Context context) {

this.context = context;

int maxDay = DateUtil.getCurrentMonthLastDay();//获取当月天数

for (int i = 0; i < DateUtil.getFirstDayOfMonth() - 1; i++) {

//DateUtil.getFirstDayOfMonth()获取当月第一天是星期几,星期日是第一天,依次类推

days.add(0);

//0代表需要隐藏的item

status.add(false);

//false代表为签到状态

}

for (int i = 0; i < maxDay; i++) {

days.add(i+1);

//初始化日历数据

status.add(false);

//初始化日历签到状态

}

}

@Override

public int getCount() {

return days.size();

}

@Override

public Object getItem(int i) {

return days.get(i);

}

@Override

public long getItemId(int i) {

return i;

}

@Override

public View getView(final int i, View view, ViewGroup viewGroup) {

ViewHolder viewHolder;

if(view==null){

view = LayoutInflater.from(context).inflate(R.layout.item_gv,null);

viewHolder = new ViewHolder();

view.setTag(viewHolder);

}else{

viewHolder = (ViewHolder) view.getTag();

}

viewHolder.tv = view.findViewById(R.id.tvWeek);

viewHolder.rlItem = view.findViewById(R.id.rlItem);

viewHolder.ivStatus = view.findViewById(R.id.ivStatus);

viewHolder.tv.setText(days.get(i)+"");

if(days.get(i)==0){

viewHolder.rlItem.setVisibility(View.GONE);

}

if(status.get(i)){

viewHolder.tv.setTextColor(Color.parseColor("#FD0000"));

viewHolder.ivStatus.setVisibility(View.VISIBLE);

}else{

viewHolder.tv.setTextColor(Color.parseColor("#666666"));

viewHolder.ivStatus.setVisibility(View.GONE);

}

view.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

if(status.get(i)){

Toast.makeText(context,"Already sign in!",Toast.LENGTH_SHORT).show();

}else{

Toast.makeText(context,"Sign in success!",Toast.LENGTH_SHORT).show();

status.set(i,true);

notifyDataSetChanged();

if(onSignedSuccess!=null){

onSignedSuccess.OnSignedSuccess();

}

}

}

});

return view;

}

class ViewHolder{

RelativeLayout rlItem;

TextView tv;

ImageView ivStatus;

}

public void setOnSignedSuccess(OnSignedSuccess onSignedSuccess){

this.onSignedSuccess = onSignedSuccess;

}

}

代码实在简单,没有什么技术上的难点,初始化数据、签到失败回调、界面效果等一些功能,大家可以自行补充。

工程源码地址:https://github.com/StormFeng/SignDate

android 签到自定义,Android日历签到,超级简单的实现方式相关推荐

  1. android 自定义圆形裁剪框,超级简单的android通过view自带的方法进行裁剪视图,实现圆形,矩形和圆角...

    使用 android:clipToOutline 属性将视图裁剪至其轮廓区域.由 如果要将视图裁剪至可绘制对象的形状,请将可绘制对象设置为视图背景(如上所示)并调用 比如说布局 xmlns:app=& ...

  2. android datepicker 自定义,Android DatePicker的简单自定义

    最近因为需求做了一个简单的选择日期的demo,我们可以同android自带的DatePicker控件达到选择日期简单联动的效果,用法挺简单的. 当在dialog在这包下android.app.Aler ...

  3. android listpreference 自定义,Android中Fragmen首选项使用自定义的ListPreference的方法

    首选项这个名词对于熟悉Android的朋友们一定不会感到陌生,它经常用来设置软件的运行参数. Android提供了一种健壮并且灵活的框架来处理首选项.它提供了简单的API来隐藏首选项的读取和持久化,并 ...

  4. android使用自定义,Android 自定义View的使用

    在Android开发中,很多自带的View满足不了我们的要求,所有我们可以自定义View来达到自己想要的效果 自定义View其实很简单也很好学,话不多说现在开始. 第一步:我们需要新建一个JAVA类 ...

  5. android numberpicker 自定义,Android的自定义数字Picker控件-NumberPicker使用方法

    android-numberpicker是github的一个项目,提供了安卓中的自定义数字拾取控件,它的效果如图所示: 应用该控件也非常简单,使用如下几步即可: 1.从github上下载该控件,地址为 ...

  6. android category 自定义,android – 自定义PreferenceCategory标题

    我有一个简单的偏好屏幕定义像这样 android:title="Require Pin on Start" android:summary="Require pin to ...

  7. android shape 自定义,Android自定义shape的使用

    MainActivity如下: package cn.testshape; import android.os.Bundle; import android.app.Activity; /** * D ...

  8. android listpreference 自定义,Android – 我的ListPreference中的自定义行布局

    在我的 Android应用程序中,我实现了从ListPreference扩展的类SubtitleColorListPreference.我需要这个,因为我需要为列表中的每个项目设置自己的布局.一切正常 ...

  9. android menu自定义,Android提高之自定义Menu(TabMenu)实现方法

    一般使用过UCWEB-Android版的人都应该对其特殊的menu有一定的印象,把menu做成Tab-Menu(支持分页的Menu),可以容纳比Android传统的menu更丰富的内容(Android ...

  10. android datepicker 自定义,android – 如何使用两个datepicker创建自定义对话框?

    最好先阅读 Dialogs和 Pickers. 至于实现,您可以有两个按钮:一个用于显示开始日期的日期选择器,另一个用于显示结束日期. 编辑:如果你真的想在1个对话框中显示2个日期选择器,这里有一个如 ...

最新文章

  1. 启用无密码方式登录ssh
  2. 更多的结构化命令(第十三章)
  3. 根据字段的不同内容分类汇总 - 球队的胜负次数统计
  4. 最优化课堂笔记06-无约束多维非线性规划方法(含重点)
  5. OpenShift 4 - Fedora CoreOS (2) - 准备 Fedora CoreOS 安装环境的三个工具
  6. 使用计算机在什么上传输,MODEM的作用是使计算机数据能在什么上传输
  7. 20. 包含min函数的栈
  8. C#基础17:匿名方法与Lambda表达式
  9. VC++开发学习一(MFC中的CString类的常用的方法技巧介绍)
  10. c# winform实现人脸识别系统(文末附源码)
  11. 咕咕数据港股实时行情数据
  12. Exchange Server 2016 CU22升级更新
  13. 黎曼猜想--黎曼1859年《论小于某给定值的素数的个数》
  14. 坪山区关于开展2022年度科技创新专项资金申报工作的通知
  15. 文曲星猜数字游戏java代码_文曲星猜数字游戏6步算法(含代码)
  16. 重新认识caniuse
  17. OAuth2实现安全登录(一)环境配置
  18. php多条件筛选前台功能,JavaScript前端数据多条件筛选功能实现代码
  19. 笔记本电脑如何锁定计算机,笔记本电脑怎么锁定关闭触摸板
  20. MySQL数据库锁介绍

热门文章

  1. CF1313 C2. Skyscrapers (hard version)
  2. vc语言c1083错误,关于VC编译错误fatal error C1083的解决办法
  3. Matlab系列之三维图形
  4. 英语复数名词的变化规则
  5. 网络计算机干啥用,路由器干什么用?路由器功能详解【图文】
  6. 防止浏览器自动填充表单
  7. Wuli智能无限的机器人已经上场了,人类律师快靠边站
  8. 筛选过的 Code rule
  9. 微型计算机的组装步骤,微型计算机系统装配教程
  10. idea 一直在updating index的问题