TimePicker時(shí)間選擇器

TimePicker時(shí)間選擇器
public class TimePicker extends View {
    private Context context;
    private Paint paintBackground,paintText,paintAlpha;

    private int width;//設(shè)置高
    private int height;//設(shè)置高

    private List<Integer> yearList,monthList,dateList,hourList;
    private List<String>minuteList;

    private int year=0,month=0,day=0,hour=0,minute=0,daysThisMonth=0;
    private String strMinute="";

    public TimePicker(Context context) {
        super(context);
        this.context=context;
        init();
    }

    public TimePicker(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
        init();
    }

    public TimePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context=context;
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawYear(canvas);
        drawMonth(canvas);
        drawDate(canvas);
        drawHour(canvas);
        drawMinute(canvas);
        drawAlpha(canvas);
    }

    /**
     * 背景
     */
    private void drawBackground(Canvas canvas) {
        paintBackground.setColor(Color.GRAY);
        canvas.drawRect(0,0,width,height,paintBackground);
        paintBackground.setColor(Color.DKGRAY);
        for (int i = 0; i < 5; i++) {
            canvas.drawRect(height/20+i*width/5,height/20,width/5-height/20+i*width/5,height*19/20,paintBackground);
            canvas.drawLine(height/20+i*width/5,height/2-height/8,width/5-height/20+i*width/5,height/2-height/8,paintText);
            canvas.drawLine(height/20+i*width/5,height/2+height/8,width/5-height/20+i*width/5,height/2+height/8,paintText);
        }
        canvas.clipRect(height/20,height/20,width-height/20,height*19/20);
    }

    /**
     * 漸變邊框
     */
    private void drawAlpha(Canvas canvas) {
        Shader mShader = new LinearGradient(height/20+width/10,height/20,height/20+width/10,height*19/20,new int[]{Color.BLACK,0x00000000,Color.BLACK},null, Shader.TileMode.CLAMP);
        paintAlpha.setShader(mShader);
        for (int i = 0; i < 5; i++) {
            canvas.drawRect(height/20+i*width/5,height/20,width/5-height/20+i*width/5,height*19/20,paintAlpha);
        }
    }

    private float yearX,yearY,yearY2;
    /**
     * 年
     */
    private void drawYear(Canvas canvas) {
        Rect rect = new Rect();
        String year=yearList.get(0)+"";
        paintText.getTextBounds(year, 0, year.length(), rect);
        for (int i = 0; i < yearList.size(); i++) {
            canvas.drawText(yearList.get(i)+"",yearX,yearY2+rect.height()/2+i*height/4,paintText);
        }
    }

    private float monthX,monthY,monthY2;
    /**
     * 月
     */
    private void drawMonth(Canvas canvas) {
        Rect rect = new Rect();
        String month=monthList.get(0)+"";
        paintText.getTextBounds(month, 0, month.length(), rect);
        for (int i = 0; i < monthList.size(); i++) {
            canvas.drawText(monthList.get(i)+"",monthX,monthY2+rect.height()/2+i*height/4,paintText);
        }
    }

    private float dateX,dateY,dateY2;
    /**
     * 日
     */
    private void drawDate(Canvas canvas) {
        Rect rect = new Rect();
        String date=dateList.get(0)+"";
        paintText.getTextBounds(date, 0, date.length(), rect);
        for (int i = 0; i < dateList.size(); i++) {
            canvas.drawText(dateList.get(i)+"",dateX,dateY2+rect.height()/2+i*height/4,paintText);
        }
    }

    private float hourX,hourY,hourY2;
    /**
     * 時(shí)
     */
    private void drawHour(Canvas canvas) {
        Rect rect = new Rect();
        String hour=hourList.get(0)+"";
        paintText.getTextBounds(hour, 0, hour.length(), rect);
        for (int i = 0; i < hourList.size(); i++) {
            canvas.drawText(hourList.get(i)+"",hourX,hourY2+rect.height()/2+i*height/4,paintText);
        }
    }

    private float minuteX,minuteY,minuteY2;
    /**
     * 分
     */
    private void drawMinute(Canvas canvas) {
        Rect rect = new Rect();
        String minute=minuteList.get(0)+"";
        paintText.getTextBounds(minute, 0, minute.length(), rect);
        for (int i = 0; i < minuteList.size(); i++) {
            canvas.drawText(minuteList.get(i)+"",minuteX,minuteY2+rect.height()/2+i*height/4,paintText);
        }
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measureWidth = getDefaultSize(getMeasuredWidth(), widthMeasureSpec);// 獲得控件的寬度
        setMeasuredDimension(measureWidth , measureWidth/3);//設(shè)置寬和高
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initTime();

        width=w;
        height=h;

        paintText.setTextSize(height/8);

        yearX=width/10;
        yearY2=height/2;
        yearLastY=yearY2;

        monthX=width/10+width/5;
        monthY2=height/2-(month+2)*height/4;
        monthLastY=monthY2;

        dateX=width/10+width*2/5;
        dateY2=height/2-(day+4)*height/4;
        dateLastY=dateY2;

        hourX=width/10+width*3/5;
        hourY2=height/2-(hour+3)*height/4;
        hourLastY=hourY2;

        minuteX=width/10+width*4/5;
        minuteY2=height/2-(minute+3)*height/4;
        minuteLastY=minuteY2;
    }

    private void init() {
        initPaint();
    }

    /**
     * 初始化時(shí)間
     */
    private void initTime() {
        Date date=new Date();
        //年
        yearList=new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        for (int i = 0; i < 30; i++) {
            yearList.add(cal.get(Calendar.YEAR)+i);
        }

        year=cal.get(Calendar.YEAR);
        month=cal.get(Calendar.MONTH)+1;
        day=cal.get(Calendar.DATE);
        hour=cal.get(Calendar.HOUR_OF_DAY);
        minute=cal.get(Calendar.MINUTE);
        if(minute<10){
            strMinute="0"+minute;
        }else {
            strMinute=""+minute;
        }

        //月份
        monthList=new ArrayList<>();
        for (int i = 0; i < 18; i++) {
            monthList.add((9+i)%12+1);
        }

        //日期
        dateList=new ArrayList<>();
        initDate();

        //小時(shí)
        hourList=new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            hourList.add((21+i)%24);
        }

        //分鐘
        minuteList=new ArrayList<>();
        for (int i = 0; i < 66; i++) {
            int minute=(57+i)%60;
            if(minute<10){
                String strMinute="0"+minute;
                minuteList.add(strMinute);
            }else {
                minuteList.add(minute+"");
            }
        }
    }

    private void initDate() {
        Date date=new Date(year,month,0);
        daysThisMonth=date.getDate();
        dateList=new ArrayList<>();
        for (int i = 0; i < daysThisMonth+10; i++) {
            dateList.add((daysThisMonth+i-5)%daysThisMonth+1);
        }
    }


    /**
     * 初始化畫(huà)筆
     */
    private void initPaint() {
        paintBackground=new Paint();
        paintBackground.setAntiAlias(true);
        paintBackground.setColor(Color.GRAY);
        paintBackground.setStyle(Paint.Style.FILL);
        paintBackground.setStrokeWidth(DensityUtil.dip2px(context,2));

        paintText=new Paint();
        paintText.setAntiAlias(true);
        paintText.setColor(Color.WHITE);
        paintText.setStyle(Paint.Style.FILL);
        paintText.setTextAlign(Paint.Align.CENTER);

        paintAlpha=new Paint();
        paintAlpha.setAntiAlias(true);
        paintAlpha.setStyle(Paint.Style.FILL);
    }

    private float downX,downY;
    private int moveIndex;
    private float yearLastY,monthLastY,dateLastY,hourLastY,minuteLastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                moveIndex=-1;
                //獲取屏幕上點(diǎn)擊的坐標(biāo)
                downX = event.getX();
                downY = event.getY();

                for (int i = 0; i < 5; i++) {
                    if(Util.isInside(downX,downY,height/20+i*width/5,height/20,width/5-height/20+i*width/5,height*19/20)){
                        moveIndex=i;
                        return true;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(moveIndex==0){
                    yearY=yearLastY+event.getY()-downY;
                    if(yearY>height/2){
                        yearY=height/2;
                    }else if(yearY<height/2-(yearList.size()-1)*height/4){
                        yearY=height/2-(yearList.size()-1)*height/4;
                    }
                    yearY2=yearY;
                    invalidate();
                }else if(moveIndex==1){
                    monthY=monthLastY+event.getY()-downY;
                    if(monthY>height/2){
                        monthY=height/2;
                    }else if(monthY<height/2-(monthList.size()-1)*height/4){
                        monthY=height/2-(monthList.size()-1)*height/4;
                    }

                    if(monthY>0){
                        monthLastY=monthLastY-12*height/4;
                        monthY=monthLastY+event.getY()-downY;
                    }else if(monthY<-13*height/4){
                        monthLastY=monthLastY+12*height/4;
                        monthY=monthLastY+event.getY()-downY;
                    }

                    monthY2=monthY;
                    invalidate();
                }else if(moveIndex==2){
                    dateY=dateLastY+event.getY()-downY;
                    if(dateY>height/2){
                        dateY=height/2;
                    }else if(dateY<height/2-(dateList.size()-1)*height/4){
                        dateY=height/2-(dateList.size()-1)*height/4;
                    }

                    if(dateY>-height/2){
                        dateLastY=dateLastY-daysThisMonth*height/4;
                        dateY=dateLastY+event.getY()-downY;
                    }else if(dateY<-(daysThisMonth+1)*height/4){
                        dateLastY=dateLastY+daysThisMonth*height/4;
                        dateY=dateLastY+event.getY()-downY;
                    }

                    dateY2=dateY;
                    invalidate();
                }else if(moveIndex==3){
                    hourY=hourLastY+event.getY()-downY;
                    if(hourY>height/2){
                        hourY=height/2;
                    }else if(hourY<height/2-(hourList.size()-1)*height/4){
                        hourY=height/2-(hourList.size()-1)*height/4;
                    }

                    if(hourY>0){
                        hourLastY=hourLastY-24*height/4;
                        hourY=hourLastY+event.getY()-downY;
                    }else if(hourY<-25*height/4){
                        hourLastY=hourLastY+24*height/4;
                        hourY=hourLastY+event.getY()-downY;
                    }

                    hourY2=hourY;
                    invalidate();
                }else if(moveIndex==4){
                    minuteY=minuteLastY+event.getY()-downY;
                    if(minuteY>height/2){
                        minuteY=height/2;
                    }else if(minuteY<height/2-(minuteList.size()-1)*height/4){
                        minuteY=height/2-(minuteList.size()-1)*height/4;
                    }

                    if(minuteY>0){
                        minuteLastY=minuteLastY-60*height/4;
                        minuteY=minuteLastY+event.getY()-downY;
                    }else if(minuteY<-61*height/4){
                        minuteLastY=minuteLastY+60*height/4;
                        minuteY=minuteLastY+event.getY()-downY;
                    }

                    minuteY2=minuteY;
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if(moveIndex==0){
                    yearLastY=yearY;
                    fixYearAnim((height/2-yearY)%(height/4));
                    int position=(int)((height/2-yearLastY+height/8)/(height/4));
                    year=yearList.get(position);
                    initDate();
                }else if(moveIndex==1){
                    monthLastY=monthY;
                    fixMonthAnim((height/2-monthY)%(height/4));
                    int position=(int)((height/2-monthLastY+height/8)/(height/4));
                    month=monthList.get(position);
                    initDate();
                }else if(moveIndex==2){
                    dateLastY=dateY;
                    fixDateAnim((height/2-dateY)%(height/4));
                    int position=(int)((height/2-dateLastY+height/8)/(height/4));
                    day=dateList.get(position);
                }else if(moveIndex==3){
                    hourLastY=hourY;
                    fixHourAnim((height/2-hourY)%(height/4));
                    int position=(int)((height/2-hourLastY+height/8)/(height/4));
                    hour=hourList.get(position);
                }else if(moveIndex==4){
                    minuteLastY=minuteY;
                    fixMinuteAnim((height/2-minuteY)%(height/4));
                    int position=(int)((height/2-minuteLastY+height/8)/(height/4));
                    strMinute=minuteList.get(position);
                }
                return true;
        }
        return super.onTouchEvent(event);
    }

    private float valueYear=0;
    private void fixYearAnim(final float slipY) {
        ValueAnimator valueAnimatorYear;
        if(slipY<=height/8){
            valueAnimatorYear= ValueAnimator.ofFloat(0f,slipY);
        }else {
            valueAnimatorYear= ValueAnimator.ofFloat(0f,slipY-height/4);
        }
        valueAnimatorYear.setDuration(300);
        valueAnimatorYear.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                valueYear= (float) animation.getAnimatedValue();
                yearY2=yearY+valueYear;
                yearLastY=yearY+valueYear;
                invalidate();
            }
        });
        valueAnimatorYear.start();
    }

    private float valueMonth=0;
    private void fixMonthAnim(final float slipY) {
        ValueAnimator valueAnimatorMonth;
        if(slipY<=height/8){
            valueAnimatorMonth= ValueAnimator.ofFloat(0f,slipY);
        }else {
            valueAnimatorMonth= ValueAnimator.ofFloat(0f,slipY-height/4);
        }
        valueAnimatorMonth.setDuration(300);
        valueAnimatorMonth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                valueMonth= (float) animation.getAnimatedValue();
                monthY2=monthY+valueMonth;
                monthLastY=monthY+valueMonth;
                invalidate();
            }
        });
        valueAnimatorMonth.start();
    }

    private float valueDate=0;
    private void fixDateAnim(final float slipY) {
        ValueAnimator valueAnimatorDate;
        if(slipY<=height/8){
            valueAnimatorDate= ValueAnimator.ofFloat(0f,slipY);
        }else {
            valueAnimatorDate= ValueAnimator.ofFloat(0f,slipY-height/4);
        }
        valueAnimatorDate.setDuration(300);
        valueAnimatorDate.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                valueDate= (float) animation.getAnimatedValue();
                dateY2=dateY+valueDate;
                dateLastY=dateY+valueDate;
                invalidate();
            }
        });
        valueAnimatorDate.start();
    }

    private float valueHour=0;
    private void fixHourAnim(final float slipY) {
        ValueAnimator valueAnimatorHour;
        if(slipY<=height/8){
            valueAnimatorHour= ValueAnimator.ofFloat(0f,slipY);
        }else {
            valueAnimatorHour= ValueAnimator.ofFloat(0f,slipY-height/4);
        }
        valueAnimatorHour.setDuration(300);
        valueAnimatorHour.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                valueHour= (float) animation.getAnimatedValue();
                hourY2=hourY+valueHour;
                hourLastY=hourY+valueHour;
                invalidate();
            }
        });
        valueAnimatorHour.start();
    }

    private float valueMinute=0;
    private void fixMinuteAnim(final float slipY) {
        ValueAnimator valueAnimatorMinute;
        if(slipY<=height/8){
            valueAnimatorMinute = ValueAnimator.ofFloat(0f,slipY);
        }else {
            valueAnimatorMinute = ValueAnimator.ofFloat(0f,slipY-height/4);
        }
        valueAnimatorMinute.setDuration(300);
        valueAnimatorMinute.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                valueMinute= (float) animation.getAnimatedValue();
                minuteY2=minuteY+valueMinute;
                minuteLastY=minuteY+valueMinute;
                invalidate();
            }
        });
        valueAnimatorMinute.start();
    }

    public String getDateStr(){
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String calender=format.format(new Date(getDate()));
        return calender;
    }

    public long getDate(){
        int position=(int)((height/2-dateLastY+height/8)/(height/4));
        day=dateList.get(position);
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            Date date=format.parse(year+"-"+month+"-"+day+" "+hour+":"+strMinute);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return new Date().getTime();
        }
    }
}

GitHub地址 https://github.com/ZuoJinDong/TimePicker

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聘芜,一起剝皮案震驚了整個(gè)濱河市兄渺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌汰现,老刑警劉巖挂谍,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異服鹅,居然都是意外死亡凳兵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)企软,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人饭望,你說(shuō)我怎么就攤上這事仗哨。” “怎么了铅辞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵厌漂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我斟珊,道長(zhǎng)苇倡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任囤踩,我火速辦了婚禮旨椒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堵漱。我一直安慰自己综慎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布勤庐。 她就那樣靜靜地躺著,像睡著了一般愉镰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丈探,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音辨宠,去河邊找鬼货裹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赋兵,可吹牛的內(nèi)容都是我干的搔预。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼历造,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吭产!你這毒婦竟也來(lái)了臣淤?” 一聲冷哼從身側(cè)響起窃爷,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤按厘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后遮咖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體造虏,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漓藕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年享钞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诀蓉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渠啤。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沥曹,死狀恐怖碟联,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壶栋,我是刑警寧澤普监,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布鹰椒,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏夺饲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一擂找、第九天 我趴在偏房一處隱蔽的房頂上張望贯涎。 院中可真熱鬧慢洋,春花似錦、人聲如沸败明。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)幔嗦。三九已至沥潭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叛氨,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工屁置, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓝角,地道東北人饭冬。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓昌抠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親裁厅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侨艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容