我设法在我的旧项目中解决了这个问题。这个想法是首先对文本进行一些预处理,以便能够在文本中只有项目符号定界符,假设在您的情况下,项目符号定界符是 "- " 根据上面的文本。然后提取每个项目符号行并使用 BulletSpan (https://developer.android.com/reference/android/text/style/BulletSpan) 进行渲染,或者如果您需要更多自定义来渲染自己的 Bullet,您可以使用 LeadingMarginSpan (https://developer.android.com/reference/android/text/style/LeadingMarginSpan ),它为您提供了使用其 drawLeadingMargin 方法绘制自定义项目符号点的灵活性。就我而言,我制作了以下 Bullet Util 类:
public class BulletUtil {
public enum BulletStyle{
Style1("•", "\u2022"),
Style2("●", "\u25CF"),
Style3("○", "\u25CB"),
Style4("▪", "\u25AA"),
Style5("■", "\u25A0"),
Style6("□", "\u25A1"),
Style7("►", "\u25BA");
private String symbol;
private String code;
private BulletStyle(String symbol, String code){
this.symbol = symbol;
this.code = code;
}
public String getCode() {
return code;
}
}
/**
* Creates Leading Margin Spans {@link LeadingMarginSpan} based on a gap width and a color integer.*
* @param originText the original Text
* @param bulletDelimiter the bullet delimiter
* @param bulletGapWidth the distance, in pixels, between the bullet point and the paragraph.
* @param bulletColor the bullet point color, as a color integer.
* @param bulletStyle the bullet style
* @return CharSequence with BulletSpans
*/
public static CharSequence addLeadingBullets(String originText, String bulletDelimiter, int bulletGapWidth, @ColorInt int bulletColor, BulletStyle bulletStyle) {
return createLeadingMarginSpans(bulletGapWidth, bulletColor, getBulletList(originText, bulletDelimiter), bulletStyle);
}
/**
* Creates Bullet Spans {@link BulletSpan} based on a gap width and a color integer.*
* @param originText the original Text
* @param bulletDelimiter the bullet delimiter
* @param bulletGapWidth the distance, in pixels, between the bullet point and the paragraph.
* @param bulletColor the bullet point color, as a color integer.
* @return CharSequence with BulletSpans
*/
public static CharSequence addBullets(String originText, String bulletDelimiter, int bulletGapWidth, @ColorInt int bulletColor) {
return createBulletSpans(bulletGapWidth, bulletColor, getBulletList(originText, bulletDelimiter));
}
/**
* Retrieves Bullet List based on a Bullet Delimiter
* @param text the Text
* @param bulletDelimiter the bullet delimiter
* @return List<String> the bullet List
*/
public static List<String> getBulletList(String text, String bulletDelimiter){
List<String> bulletLines = Arrays.asList(text.split(bulletDelimiter));
List<String> bulletList = new ArrayList<>();
if(bulletLines!=null && bulletLines.size()>0){
for(int i=0; i<bulletLines.size(); i++){
String bulletLine = bulletLines.get(i);
if(!TextUtils.isEmpty(bulletLine)){
bulletList.add(bulletLine);
}
}
}
return bulletList;
}
/**
* Creates Bullet Spans {@link BulletSpan} based on a gap width and a color integer.
*
* @param bulletGapWidth the distance, in pixels, between the bullet point and the paragraph.
* @param bulletColor the bullet point color, as a color integer.
* @param bulletList the bullet List lines
*/
public static CharSequence createBulletSpans(int bulletGapWidth, @ColorInt int bulletColor, @NonNull List<String> bulletList) {
SpannableStringBuilder sbb = new SpannableStringBuilder();
for(int i=0; i<bulletList.size(); i++){
CharSequence bulletLine = bulletList.get(i) + (i < bulletList.size()-1 ? "\n" : "");
Spannable spannable = new SpannableString(bulletLine);
BulletSpan bulletSpan = new BulletSpan(bulletGapWidth, bulletColor);
spannable.setSpan(bulletSpan, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
sbb.append(spannable);
}
return sbb;
}
/**
* Creates Bullet LeadingMarginSpans {@link LeadingMarginSpan} based on a gap width and a color integer.
*
* @param bulletGapWidth the distance, in pixels, between the bullet point and the paragraph.
* @param bulletColor the bullet point color, as a color integer.
* @param bulletList the bullet List lines
* @param bulletStyle the bullet enum Style
*/
public static CharSequence createLeadingMarginSpans(int bulletGapWidth, @ColorInt int bulletColor, @NonNull List<String> bulletList, BulletStyle bulletStyle) {
SpannableStringBuilder sbb = new SpannableStringBuilder();
for(int i=0; i<bulletList.size(); i++){
CharSequence bulletLine = bulletList.get(i) + (i < bulletList.size()-1 ? "\n" : "");
Spannable spannable = new SpannableString(bulletLine);
String bulletPointStyle = bulletStyle.getCode();
LeadingMarginSpan bulletLeadingMarginSpan = new LeadingMarginSpan()
{
@Override
public int getLeadingMargin(boolean first) {
return bulletPointStyle.length()*bulletGapWidth;
}
@Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
if (first) {
Paint.Style orgStyle = p.getStyle();
p.setStyle(Paint.Style.FILL);
p.setColor(bulletColor);
c.drawText(bulletPointStyle + " ", 0, bottom - p.descent(), p);
p.setColor(Color.BLACK);
p.setStyle(orgStyle);
}
}
};
spannable.setSpan(bulletLeadingMarginSpan, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
sbb.append(spannable);
}
return sbb;
}
}
我使用 BulletSpan 如下调用它:
String text = "- Enhanced base performance. - Lightweight headband enhances comfort and adds durability - Easy to adjust headband ensures optimum fit and comfort - 2 metre-long cable";
bulletTextView.setText(BulletUtil.addBullets(text, "- ", 100, getResources().getColor(android.R.color.holo_red_dark)));
或使用 LeadingMarginSpan:
String text = "- Enhanced base performance. - Lightweight headband enhances comfort and adds durability - Easy to adjust headband ensures optimum fit and comfort - 2 metre-long cable";
bulletTextView.setText(BulletUtil.addLeadingBullets(text, "- ", 100, getResources().getColor(android.R.color.black), BulletUtil.BulletStyle.Style2));
我在上述示例中使用了您的示例数据。