Android 自定义View-组合自定义-日历控件

本文出自简书:尧沐,如需转载请标明出处,尊重原创谢谢
博客地址:http://www.jianshu.com/p/6f40fb8d64e6
自定义View学习很久了,一直想写点什么巩固一下自己,从最简单的自定一个日历开始吧
组合控件就是用系统已经封装好的东西然后加以组合形成一个我们需要的东西,相对于各种画出来的简单很多很多。由易到难

1507346319(1).jpg

首先我们看一下日历-没错这就是win10自带的 注意看红色字体,是每个地方的组成,这么一看是不是简单很多很多

接下来写布局- -写布局注意几点 不要嵌套很深,这样解析会慢(最近看书学的优化~ ~)
说实在的很不想写布局这种东西 麻烦的一逼 你就当我写好了吧- -

因为是组合控件 所以就不是继承VIew 而是一个布局 我这里继承线性布局

然后实现三个构造方法

   @RequiresApi(api = Build.VERSION_CODES.N)
    public DataView(Context context) {
        super(context);
        initFindIdAndLinsen(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public DataView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initFindIdAndLinsen(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public DataView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initFindIdAndLinsen(context);
    }

initFindIdAndLinsen 这个方法是绑定控件以及设置监听
里面的代码很简单

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void initFindIdAndLinsen(final Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.view_calendar, this);

        mWeekUp = (ImageView) findViewById(R.id.week_up);
        mWeeknExt = (ImageView) findViewById(R.id.weekn_ext);
        mWeekToday = (TextView) findViewById(R.id.week_today);
        mWeekRecy = (RecyclerView) findViewById(R.id.week_recy);

        renderCalender(context);

        mWeekUp.setOnClickListener(new OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                calendata.add(Calendar.MONTH, -1);
                renderCalender(context);
            }


        });
        mWeeknExt.setOnClickListener(new OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                calendata.add(Calendar.MONTH, 1);
                renderCalender(context);
            }
        });
    }

这些都没什么好说的对吧,其实难点就一个 就是日期的计算


1507346319(1).jpg

注意看,我这个月的第一天是1号 他在星期日的位置 主要就是这个的计算,这个要怎么算呢

   /**
     * 渲染界面
     *
     * @param context
     */

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void renderCalender(Context context) {
        /**
         * 时间格式化
         */
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM yyyy");
        mWeekToday.setText(simpleDateFormat.format(calendata.getTime()));

        /**
         * 为了不污染 本身的时间所以复制一个
         */
        Calendar calendarOne = (Calendar) calendata.clone();
        List<Date> mDate = new ArrayList<>();

        /**
         * 把日期放在第一天 然后看最后一个周末剩下几天 然后位移
         */
        calendarOne.set(Calendar.DAY_OF_MONTH, 1);
        calendarOne.add(Calendar.DAY_OF_MONTH, - calendarOne.get(Calendar.DAY_OF_WEEK) - 1);

        /**
         * 装数据进去
         */
        while (mDate.size() < 42) {
            mDate.add(calendarOne.getTime());
            calendarOne.add(Calendar.DAY_OF_MONTH, 1);
        }

        /**
         * recylerview的Adapert总会把- -
         */
        DataViewAdapter dataViewAdapter = new DataViewAdapter(R.layout.item_data, mDate);
        mWeekRecy.setAdapter(dataViewAdapter);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 7);
        mWeekRecy.setLayoutManager(gridLayoutManager);
    }

这样这个控件就好了,难的地方就在怎么算日期上面 - -

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,143评论 25 709
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,276评论 4 61
  • 早上起来看儿子房间的灯亮着,在厨房做饭的时候儿子说要吃热干面,我问他要对他狠心的话是否当真?他没有回答,但拒绝下楼...
    周华14134阅读 338评论 1 3
  • 给wuli倩倩 今天是1月19日22:43,刚和我家倩倩道完晚安。突然好想写点什么,给她。 我们关系很好,几乎所有...
    刘小明阅读 740评论 0 1
  • 嗯~今天我们换风格了讲两只小鸡仔的故事,四不四很期待(挑眉) 人物有:小黄,小仔 (一天早上,大雪纷飞~不用说,冬...
    兮fany阅读 417评论 0 1