如何在api级别28以下使用BulletSpan(gapWidth,color,bulletRadius)?我无法将bulletRadius设置为低于api级别28。将不胜感激。
答案 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移植到您的应用程序项目中,因此您可以使用移植的版本来实现半径的设置。