美文网首页Android自定义控件Android开发Android技术知识
Android日历签到,超级简单的实现方式

Android日历签到,超级简单的实现方式

作者: StormFeng | 来源:发表于2017-08-16 11:20 被阅读514次

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

    先预览下效果图

    未签到效果.png 已签到效果.png

    分析控件结构:
    从上到下依次是TextView→GridView→GridView
    布局代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        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">
        <TextView
            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"/>
        <com.lida.signdate.InnerGridView
            android:id="@+id/gvWeek"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:numColumns="7">
        </com.lida.signdate.InnerGridView>
        <com.lida.signdate.InnerGridView
            android:id="@+id/gvDate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:numColumns="7">
        </com.lida.signdate.InnerGridView>
    </LinearLayout>
    

    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<Integer> days = new ArrayList<>();
        //日历数据
        private List<Boolean> 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

    相关文章

      网友评论

      • sun_wenming:谢谢您的分享
      • Android调调:最近项目正好用到一个签到功能 先收藏下来明天试试 谢谢分享

      本文标题:Android日历签到,超级简单的实现方式

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