首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自定义 View 实战 07 - 字母栏

自定义 View 实战 07 - 字母栏

作者头像
code_horse
发布2020-07-15 16:12:06
3120
发布2020-07-15 16:12:06
举报
文章被收录于专栏:Android NoteAndroid NoteAndroid Note

字母栏

效果分析:

  • 绘制 26 个字母
  • 处理手势事件
自定义属性
<declare-styleable name="LetterView">
        //绘制的文字大小
        <attr name="letterSize" format="dimension"/>
        //绘制文字的默认颜色
        <attr name="letterColor" format="reference|color" />
</declare-styleable>
初始化属性
    private var mNormalPaint = TextPaint()
    private var mSelectPaint = TextPaint()
    private var mLetters = arrayOf("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
    private var mCurPosition = -1

    init {
        val ta = context.obtainStyledAttributes(attributes, R.styleable.LetterView)
        val letterSize = ta.getDimensionPixelSize(R.styleable.LetterView_letterSize, sp2Px(14,resources))
        val letterColor = ta.getColor(R.styleable.LetterView_letterColor,Color.BLACK)
        ta.recycle()

        mNormalPaint.textSize = letterSize.toFloat()
        mNormalPaint.color = letterColor

        mSelectPaint.textSize = letterSize.toFloat()
        mSelectPaint.color = Color.RED
    }
测量
 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //宽度 = 左内边距 + 右内边距 + 文字的宽度
        val width = paddingLeft + paddingRight + mNormalPaint.measureText(mLetters[0]).toInt()
        val height = MeasureSpec.getSize(heightMeasureSpec)
        setMeasuredDimension(width,height)
    }
绘制
override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
            val x = (width - mNormalPaint.measureText(mLetters[0]))/2
            //获取字母的高度
            val letterHeight = (height - paddingTop - paddingBottom)/mLetters.size
        for(i in mLetters.indices){
            val deltaY = (mNormalPaint.fontMetricsInt.bottom - mNormalPaint.fontMetricsInt.top)/2-mNormalPaint.fontMetricsInt.bottom
            val baseY = deltaY + letterHeight/2 + letterHeight * i
            if(i == mCurPosition){
                canvas.drawText(mLetters[i],x,baseY.toFloat(),mSelectPaint)
            }else{
                canvas.drawText(mLetters[i],x,baseY.toFloat(),mNormalPaint)
            }
        }
    }
手势
override fun onTouchEvent(event: MotionEvent): Boolean {
        when(event.action){
            MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE->{
                val y= event.y
                val position  = (y / ((height - paddingTop - paddingBottom) / mLetters.size)).toInt()
                //如果当前 position 与之前 position 相同则不需要重新绘制
                if(position == mCurPosition){
                    return false
                }
                mCurPosition = position
                invalidate()
            }
        }
        return true
    }

项目地址

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自定义属性
  • 初始化属性
  • 测量
  • 绘制
  • 手势
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档