使用数据库中的项目符号点格式化多文本

问题描述

我有一个TextView,可在其中显示数据库中的文本,其中可以包含项目符号点:

Example Content

我的TextView位于带有LinearLayout的ScrollView中,没有什么特别之处:

       <TextView
            android:id="@+id/textview_quiz_infotext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scrollbars="vertical"
            tools:text="- This is the text" />

当文本超过一行时,我想添加与第一行相同的间距。 所以看起来像这样:

enter image description here

是否有可能实现这种行为?

解决方法

我也在尝试做同样的事情。我使用RecyclerView和适配器对其进行了尝试,然后找到了本文。下面的文章是在android中实现项目符号列表的最佳方法。 https://itnext.io/un-ordered-lists-on-android-20defac6b156

,

我设法在旧项目中一次解决了这个问题。想法是先对文本进行一些预处理,以便在文本中仅包含项目符号定界符,并根据您的情况假设项目符号定界符为“-” 。然后提取每个项目符号行,并使用 BulletSpan https://developer.android.com/reference/android/text/style/BulletSpan)进行渲染,或者,如果需要更多自定义来呈现自己的项目符号,则可以使用 LeadingMarginSpan ({ {3}})为您提供了使用其 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,as a color integer.
     * @return CharSequence with BulletSpans
     */
    public static CharSequence addBullets(String originText,@ColorInt int bulletColor) {
        return createBulletSpans(bulletGapWidth,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,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,@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,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,as a color integer.
     * @param bulletList         the bullet List lines
     * @param bulletStyle        the bullet enum Style
     */
    public static CharSequence createLeadingMarginSpans(int bulletGapWidth,@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 + " ",bottom - p.descent(),p);
                        p.setColor(Color.BLACK);
                        p.setStyle(orgStyle);
                    }
                }
            };
            spannable.setSpan(bulletLeadingMarginSpan,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,getResources().getColor(android.R.color.black),BulletUtil.BulletStyle.Style2));

我在上述示例中使用了您的示例数据。