i'm using BulletSpan which is customized. i want to display long text that has '\n'. every lines are fine except for the text line which has '\n'. bulleetspan can't apply the indent to the newline text. this is the result.
and the last text is one text. and the text has '\n' inside.
and the code is..
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val source = listOf("Spans are powerful markup objects that you can use to style text at a character or paragraph level.",
"By attaching spans to text objects, you can change text in a variety of ways, ",
"including adding color, making the text clickable,\scaling the text size,\nand drawing text in a customized way.")
val sb = SpannableStringBuilder()
for (i in source.indices) {
val length = sb.length
sb.append(source[i])
sb.append("\n")
sb.setSpan(CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), length, length + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
}
binding.tvResult.text = sb
}
private fun dip(dp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
resources.displayMetrics
).toInt()
}
private fun color(): Int {
return ContextCompat.getColor(applicationContext, R.color.gray);
}
}
and the customBullentSpan code is..
class CustomBulletSpan(
val bulletRadius: Int = STANDARD_BULLET_RADIUS,
val gapWidth: Int = STANDARD_GAP_WIDTH,
val mColor: Int = STANDARD_COLOR,
val mWantColor: Boolean = false
) : LeadingMarginSpan {
companion object {
// Bullet is slightly bigger to avoid aliasing artifacts on mdpi devices.
private const val STANDARD_BULLET_RADIUS = 4
private const val STANDARD_GAP_WIDTH = 2
private const val STANDARD_COLOR = 0
}
private var mBulletPath: Path? = null
override fun getLeadingMargin(first: Boolean): Int {
return 2 * bulletRadius + gapWidth
}
override fun drawLeadingMargin(
c: Canvas,
p: Paint,
x: Int,
dir: Int,
top: Int,
baseline: Int,
bottom: Int,
text: CharSequence,
start: Int,
end: Int,
first: Boolean,
layout: Layout?
) {
if ((text as Spanned).getSpanStart(this) == start) {
val style = p.style
p.style = Paint.Style.FILL
var oldColor = 0
if (mWantColor) {
oldColor = p.color
p.color = mColor
}
val yPosition = if (layout != null) {
val line = layout.getLineForOffset(start)
layout.getLineBaseline(line).toFloat() - bulletRadius * 1.3f
} else {
(top + bottom) / 1.3f
}
val xPosition = (x + dir * bulletRadius).toFloat()
if (c.isHardwareAccelerated) {
if (mBulletPath == null) {
mBulletPath = Path()
mBulletPath!!.addCircle(0.0f, 0.0f, bulletRadius.toFloat(), Path.Direction.CW)
}
c.save()
c.translate(xPosition, yPosition)
c.drawPath(mBulletPath!!, p)
c.restore()
} else {
c.drawCircle(xPosition, yPosition, bulletRadius.toFloat(), p)
}
if (mWantColor) {
p.color = oldColor
}
p.style = style
}
}
}
how can i solve this problem??
You could just get the string and split by \n and apply span
The other way is to split and add it to new list and iterate over the same and apply spans