注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

姑射道人的博客

博客新地址:nixuchen.com

 
 
 

日志

 
 

MagicTextView 设置textiew边框  

2013-01-09 11:34:54|  分类: android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
package com.qwerjk.better_text;

import java.util.ArrayList;
import java.util.WeakHashMap;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.widget.TextView;

public class MagicTextView extends TextView {
    private ArrayList<Shadow> outerShadows;
    private ArrayList<Shadow> innerShadows;
    
    private WeakHashMap<String, Pair<Canvas, Bitmap>> canvasStore;
    
    private Canvas tempCanvas;
    private Bitmap tempBitmap;
    
    private Drawable foregroundDrawable;
    
    private float strokeWidth;
    private Integer strokeColor;
    private Join strokeJoin;
    private float strokeMiter;
    
    private int[] lockedCompoundPadding;
    private boolean frozen = false;

    public MagicTextView(Context context) {
        super(context);
        init(null);
    }
    public MagicTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }
    public MagicTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }
    
    public void init(AttributeSet attrs){
        outerShadows = new ArrayList<Shadow>();
        innerShadows = new ArrayList<Shadow>();
        if(canvasStore == null){
            canvasStore = new WeakHashMap<String, Pair<Canvas, Bitmap>>();
        }
    
        if(attrs != null){
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MagicTextView);
            
            String typefaceName = a.getString( R.styleable.MagicTextView_typeface);
            if(typefaceName != null) {
                Typeface tf = Typeface.createFromAsset(getContext().getAssets(), String.format("fonts/%s.ttf", typefaceName));
                setTypeface(tf);
            }
            
            if(a.hasValue(R.styleable.MagicTextView_foreground)){
                Drawable foreground = a.getDrawable(R.styleable.MagicTextView_foreground);    
                if(foreground != null){
                    this.setForegroundDrawable(foreground);
                }else{
                    this.setTextColor(a.getColor(R.styleable.MagicTextView_foreground, 0xff000000));
                }
            }
        
            if(a.hasValue(R.styleable.MagicTextView_background)){
                Drawable background = a.getDrawable(R.styleable.MagicTextView_background);
                if(background != null){
                    this.setBackgroundDrawable(background);
                }else{
                    this.setBackgroundColor(a.getColor(R.styleable.MagicTextView_background, 0xff000000));
                }
            }
            
            if(a.hasValue(R.styleable.MagicTextView_innerShadowColor)){
                this.addInnerShadow(a.getFloat(R.styleable.MagicTextView_innerShadowRadius, 0),
                                    a.getFloat(R.styleable.MagicTextView_innerShadowDx, 0),
                                    a.getFloat(R.styleable.MagicTextView_innerShadowDy, 0),
                                    a.getColor(R.styleable.MagicTextView_innerShadowColor, 0xff000000));
            }
            
            if(a.hasValue(R.styleable.MagicTextView_outerShadowColor)){
                this.addOuterShadow(a.getFloat(R.styleable.MagicTextView_outerShadowRadius, 0),
                                    a.getFloat(R.styleable.MagicTextView_outerShadowDx, 0),
                                    a.getFloat(R.styleable.MagicTextView_outerShadowDy, 0),
                                    a.getColor(R.styleable.MagicTextView_outerShadowColor, 0xff000000));
            }
            
            if(a.hasValue(R.styleable.MagicTextView_strokeColor)){
                float strokeWidth = a.getFloat(R.styleable.MagicTextView_strokeWidth, 1);
                int strokeColor = a.getColor(R.styleable.MagicTextView_strokeColor, 0xff000000);
                float strokeMiter = a.getFloat(R.styleable.MagicTextView_strokeMiter, 10);
                Join strokeJoin = null;
                switch(a.getInt(R.styleable.MagicTextView_strokeJoinStyle, 0)){
                case(0): strokeJoin = Join.MITER; break;
                case(1): strokeJoin = Join.BEVEL; break;
                case(2): strokeJoin = Join.ROUND; break;
                }
                this.setStroke(strokeWidth, strokeColor, strokeJoin, strokeMiter);
            }
        }
    }
    
    public void setStroke(float width, int color, Join join, float miter){
        strokeWidth = width;
        strokeColor = color;
        strokeJoin = join;
        strokeMiter = miter;
    }
    
    public void setStroke(float width, int color){
        setStroke(width, color, Join.MITER, 10);
    }
    
    public void addOuterShadow(float r, float dx, float dy, int color){
        if(r == 0){ r = 0.0001f; }
        outerShadows.add(new Shadow(r,dx,dy,color));
    }
    
    public void addInnerShadow(float r, float dx, float dy, int color){
        if(r == 0){ r = 0.0001f; }
        innerShadows.add(new Shadow(r,dx,dy,color));
    }
    
    public void clearInnerShadows(){
        innerShadows.clear();
    }
    
    public void clearOuterShadows(){
        outerShadows.clear();
    }
    
    public void setForegroundDrawable(Drawable d){
        this.foregroundDrawable = d;
    }
    
    public Drawable getForeground(){
        return this.foregroundDrawable == null ? this.foregroundDrawable : new ColorDrawable(this.getCurrentTextColor());
    }

    
    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);
        
        freeze();
        Drawable restoreBackground = this.getBackground();
        Drawable[] restoreDrawables = this.getCompoundDrawables();
        int restoreColor = this.getCurrentTextColor();
        
        this.setCompoundDrawables(null,  null, null, null);

        for(Shadow shadow : outerShadows){
            this.setShadowLayer(shadow.r, shadow.dx, shadow.dy, shadow.color);
            super.onDraw(canvas);
        }
        this.setShadowLayer(0,0,0,0);
        this.setTextColor(restoreColor);
        
        if(this.foregroundDrawable != null && this.foregroundDrawable instanceof BitmapDrawable){
            generateTempCanvas();
            super.onDraw(tempCanvas);
            Paint paint = ((BitmapDrawable) this.foregroundDrawable).getPaint();
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
            this.foregroundDrawable.setBounds(canvas.getClipBounds());
            this.foregroundDrawable.draw(tempCanvas);
            canvas.drawBitmap(tempBitmap, 0, 0, null);
            tempCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        }

        if(strokeColor != null){
            TextPaint paint = this.getPaint();
            paint.setStyle(Style.STROKE);
            paint.setStrokeJoin(strokeJoin);
            paint.setStrokeMiter(strokeMiter);
            this.setTextColor(strokeColor);
            paint.setStrokeWidth(strokeWidth);
            super.onDraw(canvas);
            paint.setStyle(Style.FILL);
            this.setTextColor(restoreColor);
        }
        if(innerShadows.size() > 0){
            generateTempCanvas();
            TextPaint paint = this.getPaint();
            for(Shadow shadow : innerShadows){
                this.setTextColor(shadow.color);
                super.onDraw(tempCanvas);
                this.setTextColor(0xFF000000);
                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
                paint.setMaskFilter(new BlurMaskFilter(shadow.r, BlurMaskFilter.Blur.NORMAL));
                
                tempCanvas.save();
                tempCanvas.translate(shadow.dx, shadow.dy);
                super.onDraw(tempCanvas);
                tempCanvas.restore();
                canvas.drawBitmap(tempBitmap, 0, 0, null);
                tempCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                
                paint.setXfermode(null);
                paint.setMaskFilter(null);
                this.setTextColor(restoreColor);
                this.setShadowLayer(0,0,0,0);
            }
        }
        
        
        if(restoreDrawables != null){
            this.setCompoundDrawablesWithIntrinsicBounds(restoreDrawables[0], restoreDrawables[1], restoreDrawables[2], restoreDrawables[3]);
        }
        this.setBackgroundDrawable(restoreBackground);
        this.setTextColor(restoreColor);

        unfreeze();
    }
    
    private void generateTempCanvas(){
        String key = String.format("%dx%d", getWidth(), getHeight());
        Pair<Canvas, Bitmap> stored = canvasStore.get(key);
        if(stored != null){
            tempCanvas = stored.first;
            tempBitmap = stored.second;
        }else{
            tempCanvas = new Canvas();
            tempBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            tempCanvas.setBitmap(tempBitmap);
            canvasStore.put(key, new Pair<Canvas, Bitmap>(tempCanvas, tempBitmap));
        }
    }

    
    // Keep these things locked while onDraw in processing
    public void freeze(){
        lockedCompoundPadding = new int[]{
                getCompoundPaddingLeft(),
                getCompoundPaddingRight(),
                getCompoundPaddingTop(),
                getCompoundPaddingBottom()
        };
        frozen = true;
    }
    
    public void unfreeze(){
        frozen = false;
    }
    
    
    @Override
    public void requestLayout(){
        if(!frozen) super.requestLayout();
    }
    
    @Override
    public void postInvalidate(){
        if(!frozen) super.postInvalidate();
    }
    
   @Override
    public void postInvalidate(int left, int top, int right, int bottom){
        if(!frozen) super.postInvalidate(left, top, right, bottom);
    }
    
    @Override
    public void invalidate(){
        if(!frozen)    super.invalidate();
    }
    
    @Override
    public void invalidate(Rect rect){
        if(!frozen) super.invalidate(rect);
    }
    
    @Override
    public void invalidate(int l, int t, int r, int b){
        if(!frozen) super.invalidate(l,t,r,b);
    }
    
    @Override
    public int getCompoundPaddingLeft(){
        return !frozen ? super.getCompoundPaddingLeft() : lockedCompoundPadding[0];
    }
    
    @Override
    public int getCompoundPaddingRight(){
        return !frozen ? super.getCompoundPaddingRight() : lockedCompoundPadding[1];
    }
    
    @Override
    public int getCompoundPaddingTop(){
        return !frozen ? super.getCompoundPaddingTop() : lockedCompoundPadding[2];
    }
    
    @Override
    public int getCompoundPaddingBottom(){
        return !frozen ? super.getCompoundPaddingBottom() : lockedCompoundPadding[3];
    }
    
    public static class Shadow{
        float r;
        float dx;
        float dy;
        int color;
        public Shadow(float r, float dx, float dy, int color){
            this.r = r;
            this.dx = dx;
            this.dy = dy;
            this.color = color;
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:qwerjk="http://schemas.android.com/apk/res/com.qwerjk.better_text"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/triangles_tiled">

    <com.qwerjk.better_text.MagicTextView
        android:textSize="78dp"
        android:textColor="#ff333333"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
       
        android:textStyle="bold"
        android:padding="10dp"
        qwerjk:foreground="@drawable/fake_luxury_tiled"
        qwerjk:innerShadowDy="2"
        qwerjk:innerShadowColor="#FF000000"
        qwerjk:innerShadowRadius="1"
        qwerjk:outerShadowDy="3"
        qwerjk:outerShadowColor="#FF0088ff"
        qwerjk:outerShadowRadius="10"
        qwerjk:strokeColor="#FFff0000"
        qwerjk:strokeJoinStyle="miter"
        qwerjk:strokeWidth="5"
        android:text="Magic" />

</LinearLayout>
  评论这张
 
阅读(902)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017