BulletSpan с новой строкой не работает в Android
я использую BulletSpan, который настроен. я хочу отобразить длинный текст с '\n'. все строки в порядке, кроме текстовой строки, в которой есть '\n'. пуля не может применить отступ к тексту новой строки. это результат.
и последний текст - это один текст. и внутри текста есть '\n'.
а код есть..
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);
}
}
и код customBullentSpan..
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
}
}
}
Как я могу решить эту проблему??
1 ответ
Вы можете просто получить строку и разделить на \n и применить диапазон
var len = 0
for (i in source.indices) {
if (source[i].contains("\n")) {
val splitted = source[i].split("\n")
for (k in splitted.indices) {
len = sb.length
sb.append(splitted[k])
sb.append("\n")
sb.setSpan(
CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), len, len + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
}
} else {
len = sb.length
sb.append(source[i])
sb.append("\n")
sb.setSpan(
CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), len, len + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
}
}
Другой способ - разделить и добавить его в новый список, повторить его и применить промежутки.
val newList = mutableListOf<String>()
for (item in source) {
if(item.contains("\n")) {
val split = item.split("\n")
for (splitItem in split){
newList.add(splitItem)
}
} else{
newList.add(item)
}
}