如何在API级别28以下的BulletSpan中设置项目符号半径?

时间:2019-07-16 13:40:35

标签: android

如何在api级别28以下使用BulletSpan(gapWidth,color,bulletRadius)?我无法将bulletRadius设置为低于api级别28。将不胜感激。

2 个答案:

答案 0 :(得分:2)

编写自定义 Bullet Span 就像一种魅力,因为您将获得画布。有了这个,你可以在你的视图中绘制任何类型/大小的子弹。

 open class CharBulletSpan(var charCode: String, gapWidth: Int, internal val bulletColor: Int, val bulletSize: Int, val alignment: Layout.Alignment,val typeface: Typeface) : BulletSpan(gapWidth, bulletColor) {
   private var isSpanStart = true
   private val space = gapWidth
   var alpha = 0f
    override fun getLeadingMargin(first: Boolean): Int { // Returns the amount of indentation as set by the LeadingMarginSpan.class
      if (!first) {
        return 0
      }
      return super.getLeadingMargin(first)
   }
     
    override fun drawLeadingMargin(canvas: Canvas, paint: Paint, x: Int, dir: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence, start: Int, end: Int, first: Boolean, layout: Layout?) {
    //This is where the magic happens. Let us get the x - translation for the bullet since we will be painting on the canvas for different text alignments
    
       isSpanStart = (text as Spanned).getSpanStart(this) == start
       val xPos = getBulletXPos(layout!!, start, x)

       val selectionStart = Selection.getSelectionStart(text)
       val selectionEnd = Selection.getSelectionEnd(text)

       //The following block is just for a fancy purpose. When we type text and press enter and the cursor is in a new line, we can apply an alpha value to the bullet/ set a transparency. If text is typed in that line , the bullet's alpha value can be changed.
       if (!text.isNullOrEmpty()) {
        if (start != end && (text.subSequence(start, end).isNotEmpty() && text.subSequence(start, end) != "\n")) {
            this.alpha = 255f
        }
        if (start == end) {
            if ((start == 1 && selectionStart == 0) || (start == selectionStart && end == selectionEnd)) { // first line
                this.alpha = 150f
                if (!isCursorVisible) {
                    this.alpha = 0f
                }
            } else if (selectionStart != start) {
                this.alpha = 0f
            }
        }
      } else if (text != null && text.isEmpty() && start == 0 && start == end) {
          this.alpha = 255f
      }
       if (isSpanStart) {
        // Now we shall fire the bullet
           renderCharBullet(canvas, paint, xPos, dir, top, baseline, bottom, text,charCode)
        }

     }

    private fun getBulletXPos(layout: Layout, start: Int, x: Int): Int {
    val width = layout.width
    val lineNo = layout.getLineForOffset(start)
    val lineLeft = layout.getLineLeft(lineNo)
    val lineWidth = layout.getLineWidth(lineNo)
    return when (alignment) {
        Layout.Alignment.NORMAL -> x
        Layout.Alignment.OPPOSITE -> x + (width - lineWidth).toInt()
        Layout.Alignment.ALIGN_CENTER -> lineLeft.toInt() - space
        else -> x
    }
}

   private fun renderCharBullet(canvas: Canvas?, paint: Paint?, x: Int, dir: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence?, charCode: String) {
    val rectF = Rect()
    val newPaint = Paint()
    newPaint.typeface = typeface
    newPaint.textSize = bulletSize
    //Constructing a new paint to compute the y - translation of the bullet for the current line
    if (!text.isNullOrEmpty()) {
        newPaint.getTextBounds(text.subSequence(0, 1).toString(), 0, text.subSequence(0, 1).length, rectF)
    }
    val oldStyle = paint?.style
    paint?.textSize = bulletSize
    paint?.typeface = typeface
    paint?.style = Paint.Style.FILL
    paint?.color = bulletColor
    paint?.alpha = alpha.toInt()


    if (canvas!!.isHardwareAccelerated) {
        canvas.save()
        canvas.translate((x + dir).toFloat(), baseline - rectF.height().div(2.0f))
        canvas.drawText(charCode, 0f, rectF.height().div(2.0f), paint!!)
        canvas.restore()
    }
    paint?.style = oldStyle
}

}

答案 1 :(得分:0)

因此具有半径参数的方法要到API级别28才会出现。对于以前的API,您可以参考此article

基本上,作者所做的是将API 28+ BulletSpan移植到您的应用程序项目中,因此您可以使用移植的版本来实现半径的设置。