Android 自定義View——拖動選擇時間控件

前段時間在項目中遇到一個自定義控件,需要實現拖動一個類似SeekBar的東西來選擇時間段。花費了一些時間和精力搞了出來。效果圖如下

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

具體的代碼和註釋在源碼中都有,這裏只貼出關鍵代碼

關鍵代碼

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        String measureHeight = "獲取文本高度";
        paint.getTextBounds(measureHeight, 0, measureHeight.length(), textound);
        //計算控件高度
        timeheight = textound.height() + marginText + blockHeight + marginTimeBlock + seekBarHeight;
        /**
         * 高度爲時間控件所需的高度,寬度佔滿屏幕寬度
         */
        setMeasuredDimension(timeWidth, timeheight);
    }
@Override
    protected void onDraw(Canvas canvas) {
        //繪製不可能選擇的時間塊
        if (disSelectBlock != null && disSelectBlock.size() > 0) {
            Rect rect = new Rect(0,0,blockWidth,blockHeight);
            RectF rectf = new RectF();
            rectf.top = marginText + textound.height();
            rectf.bottom = textound.height() + blockHeight;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.outWidth = blockWidth;
            options.outHeight = blockHeight;
            Bitmap notSelectBg = BitmapFactory.decodeResource(getResources(),R.drawable.time_disselect_bg,options);
            for (int i = 0; i < disSelectBlock.size(); i++) {
                rectf.left =disSelectBlock.get(i) * blockWidth;
                rectf.right = disSelectBlock.get(i) * blockWidth+blockWidth;
                canvas.drawBitmap(notSelectBg,rect,rectf,null);
            }
        }
        //繪製文字
        paint.setColor(getResources().getColor(R.color.white));
        int time = beginTime;
        int lineStartY = 0;//繪製分割線的起始縱座標
        int lineEndX = textound.height() + blockHeight;//繪製分割線的終止縱座標
        for (int i = 0; i < timeBlockNum; i++) {
            if (i % 2 == 0) {
                String timeText = time + "時";
                paint.getTextBounds(timeText, 0, timeText.length(), textound);
                canvas.drawText(timeText, blockWidth + blockWidth * i - textound.height(), textound.height(), paint);
                time++;
                //短的分割線的起始縱座標
                lineStartY = textound.height() + blockHeight / 2;
            } else {
                //長的分割線的起始縱座標
                lineStartY = textound.height();
            }
            lineStartY += marginText;
            //繪製時間塊分割線
            canvas.drawLine(blockWidth * i, lineStartY, blockWidth * i, lineEndX, paint);
        }
        //繪製最後端的一條分割短線
        canvas.drawLine(timeWidth, lineStartY + blockHeight / 2, timeWidth, lineEndX, paint);

        paint.setStrokeWidth(1);
        paint.setColor(getResources().getColor(R.color.gray));

        //繪製拖動條頂部的線條
        canvas.drawLine(0, timeheight - seekBarHeight, timeWidth, timeheight - seekBarHeight, paint);
        //繪製拖動條底部的線條
        paint.setStrokeWidth(2);
        canvas.drawLine(0, timeheight, timeWidth - 2, timeheight - 2, paint);

        if (seekBarStart != 0) {
            //繪製拖動條尾部
            paint.setStrokeWidth(0);
            paint.setColor(getResources().getColor(R.color.color_fabe00));
            int disNum = seekBarEnd - seekBarStart;
            int startX = seekBarStart * blockWidth + bodyDistance;
            if (startX < blockWidth) {
                startX = blockWidth;
            } else if (startX > timeWidth - blockWidth - disNum * blockWidth) {
                startX = timeWidth - blockWidth - disNum * blockWidth;
            }
            int endX = seekBarEnd * blockWidth + moveDistance + bodyDistance;
            if (endX > timeWidth - blockWidth) {
                endX = timeWidth - blockWidth;
            } else if (bodyDistance != 0 && endX < startX + blockWidth * disNum) {
                endX = startX + blockWidth * disNum;
            } else if (endX < startX + blockWidth) {
                endX = startX + blockWidth;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                canvas.drawRoundRect(startX, timeheight - seekBarHeight + 10, endX, timeheight - 10, 4, 4, paint);
            } else {
                canvas.drawRect(startX, timeheight - seekBarHeight + 10, endX, timeheight - 10, paint);
            }
            //繪製拖動條頭部圓圈
            paint.setColor(getResources().getColor(R.color.color_eb7938));
            canvas.drawCircle(endX, timeheight - seekBarHeight / 2, seekBarHeight / 2, paint);
            paint.setColor(getResources().getColor(R.color.white));
            canvas.drawCircle(endX, timeheight - seekBarHeight / 2, seekBarHeight / 4, paint);
        }
    }

——————————————————————

源碼地址

發佈了32 篇原創文章 · 獲贊 111 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章