美文网首页
标题带标签

标题带标签

作者: xfg0321 | 来源:发表于2019-05-21 10:54 被阅读0次

    在开发的过程中,可能会遇到过标题里面带标签。比如入下图

    image

    实现的方式可能有好几种,比如html等。但是这个方式麻烦,并且耗内存。android 提供强大的SpannableString。具体实现直接上代码。

    .....

    public class TagsTextView extends android.support.v7.widget.AppCompatTextView {
    private Context mContext;
    SpannableString span ;
    StringBuilder builder = new StringBuilder();
    private String value;
    ArrayList<String > mTags;
    float padding = 0;
    float margin ;
    float radius;
    float textSize ;
    float tagPaddingTopBottom;
    float titleTextSize;
    public TagsTextView(Context context) {
    this(context,null);
    }

    public TagsTextView(Context context, AttributeSet attrs) {
       this(context,attrs,0);
    }
    
    public TagsTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    
        padding = UiUtils.dip2px(mContext,5);
        margin = UiUtils.dip2px(mContext,4);
        radius = UiUtils.dip2px(mContext,2);
        textSize = UiUtils.dip2px(mContext,10);
        titleTextSize = UiUtils.dip2px(mContext,14);
    
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TagsTextView);
        padding = ta.getDimension(R.styleable.TagsTextView_tagPaddingLeftRight,padding);
        margin = ta.getDimension(R.styleable.TagsTextView_tagMargin,margin);
        radius = ta.getDimension(R.styleable.TagsTextView_tagRadius,radius);
        textSize = ta.getDimension(R.styleable.TagsTextView_tagTextSize,textSize);
        titleTextSize = ta.getDimension(R.styleable.TagsTextView_titleTextSize,titleTextSize);
        tagPaddingTopBottom = ta.getDimension(R.styleable.TagsTextView_tagPaddingTopBottom,tagPaddingTopBottom);
    }
    
    private void init(Context context){
        this.mContext = context;
    
    }
    
    public TagsTextView setTextStr(String value){
    
        this.value = value;
    
        return this;
    }
    
    
    public TagsTextView addTags(ArrayList<String > tags){
        this.mTags = tags;
    
    
        return this;
    }
    
    public void build(){
        builder.delete(0, builder.length());
    
        int start = 0;
        if(null != mTags && mTags.size() > 0){
            for(int i = 0;i<mTags.size() ;i++){
                String str =  mTags.get(i) ;
                builder.append(str);
            }
            builder.append(value);
            span = new SpannableString(builder);
            for(int i = 0;i<mTags.size() ;i++){
                String str = mTags.get(i) ;
                int color = getColorWithTag(mTags.get(i));
                span.setSpan(new RoundBackgroundColorSpan(color,Color.WHITE),start,start + str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                span.setSpan(new AbsoluteSizeSpan((int) textSize), start,start + str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                start += str.length();
            }
            span.setSpan(new AbsoluteSizeSpan((int) titleTextSize), start,builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }else{
            builder.append(value);
            span = new SpannableString(builder);
            span.setSpan(new AbsoluteSizeSpan((int) titleTextSize), 0,builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    
        setText(span);
    }
    
    private int getColorWithTag(String tag){
        if(tag.equals("新品")){
            return Color.parseColor("#20D6AC");
        }else if(tag.equals("特卖")){
            return Color.parseColor("#E9A433");
        }else if(tag.equals("精选")){
            return Color.parseColor("#A372FF");
        }
        return Color.parseColor("#20D6AC");
    }
    
    public class RoundBackgroundColorSpan extends ReplacementSpan {
        private int bgColor;
        private int textColor;
        public RoundBackgroundColorSpan(int bgColor, int textColor) {
            super();
            this.bgColor = bgColor;
            this.textColor = textColor;
        }
        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
            //设置宽度为文字宽度加16dp
            return (int) (paint.measureText(text, start, end)+padding * 2 + margin);
        }
    
    
        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            int originalColor = paint.getColor();
            paint.setColor(this.bgColor);
            paint.setTextSize(textSize);
    
            Paint.FontMetrics metrics = paint.getFontMetrics();
            float textHeight = metrics.descent - metrics.ascent;
    
            System.out.println("textHeight:" + textHeight + "   textsize:"+textSize);
            System.out.println("same:"+ (metrics.descent - metrics.ascent));
            System.out.println("x:" + x +"   y:"+y+"  top:"+top + "   bottom:"+bottom);
    
            //画圆角矩形背景,调试调整背景的位置。
            canvas.drawRoundRect(new RectF(x ,
                            top + (titleTextSize - textSize)  - UiUtils.dip2px(mContext,tagPaddingTopBottom-1)  , //因为文本本身顶部会有2个dp的默认间距,先将所有的对齐之后,再调整布局。
                            x + ((int) paint.measureText(text, start, end)+ 2 * padding),
                            top + (( metrics.descent  - metrics.ascent) )  +UiUtils.dip2px(mContext,2)  +  2 * UiUtils.dip2px(mContext,tagPaddingTopBottom) )
                    ,
    
                    radius,
                    radius,
                    paint);
            paint.setColor(this.textColor);
    
    
            //画文字,两边各增加8dp
    
            //因为字体要默认居中,因此要计算。默认顶部对齐。设置文字的位置。
            canvas.drawText(text, start, end, x + padding, y - (titleTextSize - textSize) / 2 + UiUtils.dip2px(mContext,1)
                    , paint);
    
    
            //将paint复原
            paint.setColor(originalColor);
    
    
        }
    }
    

    }

    ......

    ........

    <declare-styleable name="TagsTextView">
    <attr name="tagPaddingTopBottom" format="dimension" />
    <attr name="tagRadius" format="dimension" />
    <attr name="tagMargin" format="dimension"/>
    <attr name="tagTextColor" format="color" />
    <attr name="tagTextSize" format="dimension" />
    <attr name="titleTextSize" format="dimension" />
    <attr name="tagPaddingLeftRight" format="dimension" />
    </declare-styleable>
    使用方式

    <TagsTextView
    android:id="@+id/tagTitle"
    android:gravity="center"
    android:background="#e0f020"
    app:tagPaddingLeftRight="5dp"
    app:tagPaddingTopBottom="1dp"
    app:tagTextSize="14dp"
    app:titleTextSize="16dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
    .........

    实现效果:


    image.png

    相关文章

      网友评论

          本文标题:标题带标签

          本文链接:https://www.haomeiwen.com/subject/hfedzqtx.html