Adding a padding/margin to a Spannable

前端 未结 2 1131
-上瘾入骨i
-上瘾入骨i 2020-12-14 09:16

I\'m using BackgroundColorSpan to customize parts of a TextView. Here\'s the code I have:

String s = \"9.5 Excellent!\";
s.setSpan(         


        
相关标签:
2条回答
  • 2020-12-14 09:35

    You can use ReplacementSpan. In your Activity:

    TextView tagsTextView = (TextView) mView.findViewById(R.id.tagsTextView);
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
    
    SpannableString tag1 = new SpannableString("9.5");
    stringBuilder.append(tag1);
    stringBuilder.setSpan(new TagSpan(getResources().getColor(R.color.blue), getResources().getColor(R.color.white)), stringBuilder.length() - tag1.length(), stringBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    SpannableString tag2 = new SpannableString("excellent!");
    stringBuilder.append(tag2);
    stringBuilder.setSpan(new TagSpan(getResources().getColor(R.color.blueLight), getResources().getColor(R.color.blue)), stringBuilder.length() - tag2.length(), stringBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    tagsTextView.setText(stringBuilder, TextView.BufferType.SPANNABLE);
    

    TagSpan.java

    public class TagSpan extends ReplacementSpan {
        private static final float PADDING = 50.0f;
        private RectF mRect;
        private int mBackgroundColor;
        private int mForegroundColor;
    
        public TagSpan(int backgroundColor, int foregroundColor) {
            this.mRect = new RectF();
            this.mBackgroundColor = backgroundColor;
            this.mForegroundColor = foregroundColor;
        }
    
        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            // Background
            mRect.set(x, top, x + paint.measureText(text, start, end) + PADDING, bottom);
            paint.setColor(mBackgroundColor);
            canvas.drawRect(mRect, paint);
    
            // Text
            paint.setColor(mForegroundColor);
            int xPos = Math.round(x + (PADDING / 2));
            int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
            canvas.drawText(text, start, end, xPos, yPos, paint);
        }
    
        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
            return Math.round(paint.measureText(text, start, end) + PADDING);
        }
    }
    
    0 讨论(0)
  • 2020-12-14 09:40

    You can use RoundedBackgroundSpan.

    1. It supports both padding and margin
    2. It avoids the situation where the text is not centered in the TextView.
    3. It can also set BackgroundColor for the text.

      public class RoundedBackgroundSpan extends ReplacementSpan {
      
      
      private final int mBackgroundColor;
      private final int mTextColor;
      private final int mPaddingLeft;
      private final int mPaddingRight;
      private final int mMarginLeft;
      private final int mMarginRight;
      
      /**
       * Add rounded background for text in TextView.
       * @param backgroundColor background color
       * @param textColor       text color
       * @param paddingLeft     padding left(including background)
       * @param paddingRight    padding right(including background)
       * @param marginLeft      margin left(not including background)
       * @param marginRight     margin right(not including background)
       */
      public RoundedBackgroundSpan(int backgroundColor, int textColor,
                                   int paddingLeft,
                                   int paddingRight,
                                   int marginLeft,
                                   int marginRight) {
          mBackgroundColor = backgroundColor;
          mTextColor = textColor;
          mPaddingLeft = paddingLeft;
          mPaddingRight = paddingRight;
          mMarginLeft = marginLeft;
          mMarginRight = marginRight;
      }
      
      @Override
      public int getSize(Paint paint, CharSequence text, int start, int end,
                         Paint.FontMetricsInt fm) {
          return (int) (mMarginLeft + mPaddingLeft +
                  paint.measureText(text.subSequence(start, end).toString()) +
                  mPaddingRight  + mMarginRight);
      }
      
      @Override
      public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
                       int bottom, Paint paint) {
          float width = paint.measureText(text.subSequence(start, end).toString());
          RectF rect = new RectF(x + mMarginLeft, top
                  - paint.getFontMetricsInt().top + paint.getFontMetricsInt().ascent
                  , x + width + mMarginLeft + mPaddingLeft + mPaddingRight, bottom);
          paint.setColor(mBackgroundColor);
          canvas.drawRoundRect(rect, rect.height() / 2, rect.height() / 2, paint);
          paint.setColor(mTextColor);
          canvas.drawText(text, start, end, x + mMarginLeft + mPaddingLeft,
                  y - paint.getFontMetricsInt().descent / 2, paint);
      }
      }
      
    0 讨论(0)
提交回复
热议问题