【问题标题】:Formatting multine Text with bullet points from Database使用数据库中的项目符号格式化多行文本
【发布时间】:2020-11-02 17:13:28
【问题描述】:

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

我的 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" />

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

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

【问题讨论】:

  • 你能添加一张运行它时外观的图像吗?

标签: android android-layout textview android-database


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我设法在我的旧项目中解决了这个问题。这个想法是首先对文本进行一些预处理,以便能够在文本中只有项目符号定界符,假设在您的情况下,项目符号定界符是 "- " 根据上面的文本。然后提取每个项目符号行并使用 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));
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多