撸一个简单的TV版焦点控制的日历控件

2019-03-20  本文已影响0人  Dane_404

1、效果

最近需求要一个遥控控制的日历控件,找了半天没找到轮子,就自己撸一个,先看效果图:


效果图.gif

2、XML属性,所有属性默认为效果图

3、抱着学习心态撸这个控件,写这篇的目的是记录分享下这个TvCalenderView

先讲个大概,TvCalenderView继承LinearLayout垂直排序,三个子View,先后为HeadView,WeekView,MonthView,就贴一些关键点。

接下来看onkeyDown:
处理遥控器的事件:
mCurRow和mCurColumn在onDraw拿到1号的位置,然后根据遥控事件拿到对应的日期,再invalidate重新绘制:

  //遥控事件
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
                if (mCurRow <= 0) {   //如果是在第0行,再按上键的话,这时MonthView会失去焦点
                    return super.onKeyDown(keyCode, event);
                }
                mCurRow--;
                mDay = mDayStr[mCurRow][mCurColumn]; //拿出存的day,后面调用invalidate重新绘制
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                if (mCurRow >= mDayStr.length - 1) {  //下限
                    return super.onKeyDown(keyCode, event);
                }
                mCurRow++;
                mDay = mDayStr[mCurRow][mCurColumn];
                if (mDay == 0) {  //拿不到的情况,比如效果图25号下面没有日期
                    mDay = mTempDay;  //mTempDay记录了上一次的日期
                    mCurRow--;   //上面加了拿不到,减回去
                }
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                if (mCurColumn <= 0) {
                    preMonth();     //往左到界限,跳到上一个月
                    return super.onKeyDown(keyCode, event);
                }
                mCurColumn--;
                mDay = mDayStr[mCurRow][mCurColumn];
                if (mDay == 0) {   //拿不到的情况,比如效果图1号左边没有日期
                    preMonth();
                    return super.onKeyDown(keyCode, event);
                }
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                if (mCurColumn >= mDayStr[0].length - 1) {
                    nextMonth();  //往右到界限,跳到下一个月
                    return super.onKeyDown(keyCode, event);
                }
                mCurColumn++;
                mDay = mDayStr[mCurRow][mCurColumn];
                if (mDay == 0) {   //拿不到的情况,比如效果图31号右边没有日期
                    nextMonth();
                    return super.onKeyDown(keyCode, event);
                }
                break;
            case KeyEvent.KEYCODE_ENTER:  //确认按钮
                if (mOnDateSeletedListener != null) {
                    mOnDateSeletedListener.onDateSelected(mYear, mMonth, mDay);
                }
                return super.onKeyDown(keyCode, event);
            default:
                return super.onKeyDown(keyCode, event);
        }
        invalidate();
        return true;
    }

    public void nextMonth() {
        if (mMonth >= 11) {
            mMonth = 0;
            mYear++;
            setYearAndMonth(mYear, mMonth);  //换月份
            ((TvCalenderView) getParent()).changeHeadData(mMonth, mYear);  //调用改变头部的日期
            return;
        }
        mMonth++;
        setYearAndMonth(mYear, mMonth);
        ((TvCalenderView) getParent()).changeHeadData(mMonth, mYear);
    }

最后

贴上Demo地址:
https://github.com/CzdCoder/TvCalenderView
分享下自定义View学习系列:
Android 开发进阶: 自定义 View 1-1 绘制基础:http://hencoder.com/ui-1-1/
Android 开发进阶: 自定义 View 1-2 Paint 详解:http://hencoder.com/ui-1-2/
Android 开发进阶:自定义 View 1-3 文字的绘制:http://hencoder.com/ui-1-3/
Android 开发进阶:自定义 View 1-4 Canvas 对绘制的辅助:http://hencoder.com/ui-1-4/
Android 开发进阶:自定义 View 1-5 绘制顺序:http://hencoder.com/ui-1-5/

上一篇下一篇

猜你喜欢

热点阅读