美文网首页
建立自己的王国:Android 自定义封装View-5

建立自己的王国:Android 自定义封装View-5

作者: 努尔江 | 来源:发表于2021-10-25 20:30 被阅读0次
    效果图
    • 要实现右边的字母索引。
    • 滑动事件响应到RecyclerView上。
    • 展示当前选中的索引值(效果图中间灰色B)。

    实现思路:

    1. 用自定义View画出字母A到Z。
    2. 重写onTouch方法定位当前字母索引。
      3.通过RecyclerViewscrollToPositionWithOffset()方法来触发定位。

    实现

    • 1.自定义View
      重写onMeasure(),onTouchEvent,onDraw()
    //设定高度,宽度值固定。
     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            setMeasuredDimension(DisplayUtils.dip2px(15F), DisplayUtils.dip2px(390F))
        }
    
    

    onDraw方法里按照定距离画出字母就可以了。

        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
            // v是字母,aList是A---Z的集合。
            for ((i, v) in aList.withIndex()) {
                canvas.drawText(
                    v.toString(),
                    DisplayUtils.dip2px(7.5F).toFloat(),
                    DisplayUtils.dip2px((15 * i) + 12F).toFloat(),
                    paint
                )
            }
        }
    

    onTouch() 方法里需要注意的是,写一个接口,让滑动和当前选中事件暴露给Activity, 方便RecyclerView滑动到指定位置。

     interface AlphabetCallBack{
    //在移动的时候调用
        fun movingChar(c:Char)
    //最后选中的位置。
        fun finished(i:Int)
    }
    

    上面的接口中的两个方法分别对应onTouch()MotionEven.ACTION_MOVEMotionEvent.ACTION_UP

    关键部分。

        override fun onTouchEvent(event: MotionEvent?): Boolean {
            val  y:Int=event?.y!!.toInt()
            if (event.action==MotionEvent.ACTION_MOVE){
                //这里把View的高度等分,找出对应的值。
                val position= (DisplayUtils.px2dip(y) - DisplayUtils.dip2px(12F))/DisplayUtils.dip2px(15F)
                if (position!=oldPosition){
                    if (callBack!=null){
                        callBack!!.movingChar(aList[position])
                    }
                    oldPosition=position
                }
            }else if (event.action==MotionEvent.ACTION_UP){
                if (callBack!=null){
                    callBack!!.finished(oldPosition)
                }
            }
          //返回true 表示事件已被消费。
            return true
        }
    

    Activity实现AlphabetCallBack

    
        override fun movingChar(c: Char) {
        //防止多次运行
            if (tvAlpha.visibility != View.VISIBLE){
                tvAlpha.text=c.toString()
                tvAlpha.visibility=View.VISIBLE
            }else{
                tvAlpha.text=c.toString()
            }
        }
        //最后选中位置.
        override fun finished(i:Int) {
          //RecyclerView的LayoutManager
                manager.scrollToPositionWithOffset(i,0)
          //延迟把View隐藏。
           Handler().postDelayed({ tvAlpha.visibility=View.GONE },500)
        }
    

    完。

    相关文章

      网友评论

          本文标题:建立自己的王国:Android 自定义封装View-5

          本文链接:https://www.haomeiwen.com/subject/objsaltx.html