自定义View之数字键盘

自定了一个数字键盘,简单记录一下:

 直接上源码

package com.example.jetcom

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View


/**
 * AUTHOR:AbnerMing
 * INTRODUCE:自定义数字键盘
 */
class KeyboardView : View {
    private var mOnPositionClickListener: OnPositionClickListener? = null
    private var mRectWidth: Int? = null
    private var mPaint: Paint? = null
    private var mSpacing = 10//键盘格子默认间隔
    private var mHeight = 100//键盘格子默认高度
    private var mWordArray =
        arrayOf("A B C", "D E F", "G H I", "J K L", "M N O", "P Q R S", "U V W", "X Y Z")

    //默认背景色
    private var mBackGroundColor = Color.parseColor("#1A1A1A")

    //默认格子背景色
    private var mRectBackGroundColor = Color.parseColor("#646465")

    //默认数字颜色
    private var mTextColor = Color.parseColor("#ffffff")

    //默认数字大小
    private var mTextSize = 50f

    constructor(
        context: Context
    ) : super(context) {
        initView(context)
    }

    constructor(
        context: Context,
        attrs: AttributeSet?
    ) : super(context, attrs) {
        initView(context)
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置整体背景色
     */
    fun setBackGroundColor(backGroundColor: Int) {
        mBackGroundColor = backGroundColor
        invalidate()
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置数字格子背景色
     */
    fun setRectBackGroundColor(rectBackGroundColor: Int) {
        mRectBackGroundColor = rectBackGroundColor
        invalidate()
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置数字颜色
     */
    fun setTextColor(textColor: Int) {
        mTextColor = textColor
        invalidate()
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置数字大小
     */
    fun setTextSize(textSize: Float) {
        mTextSize = textSize
        invalidate()
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置数字键盘每格高度
     */
    fun setRectHeight(height: Int) {
        mHeight = height
        invalidate()
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:设置数字键盘每格间隔距离
     */
    fun setSpacing(spacing: Int) {
        mSpacing = spacing
        invalidate()
    }

    private fun initView(context: Context) {
        setBackgroundColor(mBackGroundColor)
        mPaint = Paint()
        mPaint!!.color = mRectBackGroundColor
        mPaint!!.strokeWidth = 10f
        mPaint!!.isAntiAlias = true
        mPaint!!.textSize = mTextSize
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        mRectWidth = (width - mSpacing * 4) / 3
        mPaint!!.strokeWidth = 10f
        //绘制数字键盘
        for (i in 0..11) {

            val rect = RectF()
            val iTemp = i / 3
            val rectTop = mHeight * iTemp + mSpacing * (iTemp + 1f)
            rect.top = rectTop
            rect.bottom = rect.top + mHeight
            var leftSpacing = (mSpacing * (i % 3f))
            leftSpacing += 10f
            rect.left = mRectWidth!! * (i % 3f) + leftSpacing
            rect.right = rect.left + mRectWidth!!

            if (i == 9 || i == 11) {
                if (i == 11) {
                    drawDelete(canvas, rect.right, rect.top)
                }
                continue
            }
            mPaint!!.textSize = mTextSize
            mPaint!!.style = Paint.Style.FILL
            mPaint!!.color = mRectBackGroundColor

            canvas!!.drawRoundRect(rect, 10f, 10f, mPaint!!)

            //绘制数字
            mPaint!!.color = mTextColor
            var keyWord = "${i + 1}"
            if (i == 10) {
                keyWord = "0"
            }
            val rectWord = Rect()
            mPaint!!.getTextBounds(keyWord, 0, keyWord.length, rectWord)
            val wWord = rectWord.width()
            val htWord = rectWord.height()
            var yWord = rect.bottom - mHeight / 2 + (htWord / 2)
            if (i != 0 && i != 10) {
                yWord -= 13
            }
            canvas.drawText(
                keyWord,
                rect.right - mRectWidth!! / 2 - (wWord / 2),
                yWord,
                mPaint!!
            )

            //绘制字母
            if (i in 1..8) {
                mPaint!!.textSize = 20f
                val s = mWordArray[i - 1]
                val rectW = Rect()
                mPaint!!.getTextBounds(s, 0, s.length, rectW)
                val w = rectW.width()
                val h = rectW.height()
                canvas.drawText(
                    s,
                    rect.right - mRectWidth!! / 2 - (w / 2),
                    rect.bottom - mHeight / 2 + (h / 2) + 25,
                    mPaint!!
                )
            }
        }

    }


    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        super.onTouchEvent(event)
        when (event!!.action) {
            MotionEvent.ACTION_UP -> {
                //手指抬起
                val upX = event.x
                val upY = event.y
                val touchPosition = getTouch(upX, upY)
                if (touchPosition != 10) {
                    if (mOnPositionClickListener != null) {
                        mOnPositionClickListener!!.positionClick(touchPosition)
                    }
                }
            }
        }
        return true
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:返回触摸的位置
     */
    fun getTouch(upX: Float, upY: Float): Int {
        var position = 1
        for (i in 0..11) {
            val iTemp = i / 3
            val rectTop = mHeight * iTemp + mSpacing * (iTemp + 1f)
            val top = rectTop
            val bottom = top + mHeight
            var leftSpacing = (mSpacing * (i % 3f))
            leftSpacing += 10f
            val left = mRectWidth!! * (i % 3f) + leftSpacing
            val right = left + mRectWidth!!
            if (upX > left && upX < right && upY > top && upY < bottom) {
                position = i + 1
                if (position == 11) {
                    position = 0
                }
                if (position == 12) {
                    position = -1
                }
            }
        }
        return position
    }


    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:点击回调
     */
    fun setOnPositionClickListener(action: (Int) -> Unit) {
        mOnPositionClickListener = object : OnPositionClickListener {
            override fun positionClick(position: Int) {
                action(position)
            }
        }
    }

    interface OnPositionClickListener {
        //-1为点击了删除按键
        fun positionClick(position: Int)
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:绘制删除按键
     */
    fun drawDelete(canvas: Canvas?, right: Float, top: Float) {
        val rWidth = 15
        val lineWidth = 35
        val x = right - mRectWidth!! / 2 - (rWidth + lineWidth) / 4
        val y = top + mHeight / 2
        val path = Path()
        path.moveTo(x - rWidth, y)
        path.lineTo(x, y - rWidth)
        path.lineTo(x + lineWidth, y - rWidth)
        path.lineTo(x + lineWidth, y + rWidth)
        path.lineTo(x, y + rWidth)
        path.lineTo(x - rWidth, y)
        path.close()
        mPaint!!.strokeWidth = 2f
        mPaint!!.style = Paint.Style.STROKE
        mPaint!!.color = mTextColor
        canvas!!.drawPath(path, mPaint!!)

        //绘制小×号
        mPaint!!.style = Paint.Style.FILL
        mPaint!!.textSize = 30f
        val word = "×"
        val rectWord = Rect()
        mPaint!!.getTextBounds(word, 0, word.length, rectWord)
        val wWord = rectWord.width()
        val htWord = rectWord.height()
        canvas.drawText(
            "×",
            right - mRectWidth!! / 2 - wWord / 2 + 3,
            y + htWord / 3 * 2 + 2,
            mPaint!!
        )

    }
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员一鸣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值