zoukankan      html  css  js  c++  java
  • Android TextView文字描边的实现!!

    Android开发:文字描边

    转自:http://www.oschina.net/code/snippet_586849_37287

    1. [代码][Java]代码     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    package com.example.testproject;
     
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint.Style;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.view.ViewGroup;
    import android.widget.TextView;
    /*
     * StrokeTextView的目标是给文字描边
     * 实现方法是两个TextView叠加,只有描边的TextView为底,实体TextView叠加在上面
     * 看上去文字就有个不同颜色的边框了
     */
    public class StrokeTextView extends TextView {
     
        private TextView borderText = null;///用于描边的TextView
     
        public StrokeTextView(Context context) {
            super(context);
            borderText = new TextView(context);
            init();
        }
     
        public StrokeTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            borderText = new TextView(context,attrs);
            init();
        }
     
        public StrokeTextView(Context context, AttributeSet attrs,
                int defStyle) {
            super(context, attrs, defStyle);
            borderText = new TextView(context,attrs,defStyle);
            init();
        }
     
        public void init(){
            TextPaint tp1 = borderText.getPaint();
            tp1.setStrokeWidth(4);                                  //设置描边宽度
            tp1.setStyle(Style.STROKE);                             //对文字只描边
            borderText.setTextColor(getResources().getColor(R.color.border_text));  //设置描边颜色
            borderText.setGravity(getGravity());
        }
     
        @Override
        public void setLayoutParams (ViewGroup.LayoutParams params){
            super.setLayoutParams(params);
            borderText.setLayoutParams(params);
        }
     
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            CharSequence tt = borderText.getText();
             
            //两个TextView上的文字必须一致
            if(tt== null || !tt.equals(this.getText())){
                borderText.setText(getText());
                this.postInvalidate();
            }
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            borderText.measure(widthMeasureSpec, heightMeasureSpec);
        }
     
        protected void onLayout (boolean changed, int left, int top, int right, int bottom){
            super.onLayout(changed, left, top, right, bottom);
            borderText.layout(left, top, right, bottom);
        }
     
        @Override
        protected void onDraw(Canvas canvas) {
            borderText.draw(canvas);
            super.onDraw(canvas);
        }
     
    }

    2. [代码][XML]代码     

    1
    2
    3
    4
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="border_text" >#ffffff</color>
    </resources>

    3. [图片] miao_bian.png    

     
     
     
    第二种方法:
    转自:http://blog.csdn.net/skyztttt/article/details/9189045

    最近在android上搞一个带描边效果的TextView,网上搜索了下都是采用两个TextView在一个layout中进行实现,但细想了下,如果我在一个TextView中让其以不同的方式进行两次描绘不就能够达到效果了吗?由于网上没有看到和我类似的方法,故发出来和大家分享,由于只需要重写protected void onDraw(Canvas canvas);方法即可,故只附上onDraw的实现:

    [java] view plain copy
     
    1.        private boolean m_bDrawSideLine = false; // 默认不采用描边  
    2.        /* (non-Javadoc) 
    3.  * @see android.widget.TextView#onDraw(android.graphics.Canvas) 
    4.  */  
    5. @Override  
    6. protected void onDraw(Canvas canvas) {  
    7.     if (m_bDrawSideLine) {  
    8.                        // 描外层  
    9.                        //super.setTextColor(Color.BLUE); // 不能直接这么设,如此会导致递归  
    10.                        setTextColorUseReflection(Color.BLUE);  
    11.                        m_TextPaint.setStrokeWidth(3);  // 描边宽度  
    12.                        m_TextPaint.setStyle(Style.FILL_AND_STROKE); //描边种类  
    13.                        m_TextPaint.setFakeBoldText(true); // 外层text采用粗体  
    14.                        m_TextPaint.setShadowLayer(1, 0, 0, 0); //字体的阴影效果,可以忽略  
    15.         super.onDraw(canvas);  
    16.                          
    17.   
    18.                        // 描内层,恢复原先的画笔  
    19.   
    20.                        //super.setTextColor(Color.BLUE); // 不能直接这么设,如此会导致递归    
    21.                        setTextColorUseReflection(Color.RED);  
    22.                        m_TextPaint.setStrokeWidth(0);                           
    23.                        m_TextPaint.setStyle(Style.FILL_AND_STROKE);                           
    24.                        m_TextPaint.setFakeBoldText(false);                          
    25.                        m_TextPaint.setShadowLayer(0, 0, 0, 0);                           
    26.               }  
    27.               super.onDraw(canvas);  
    28.        }  
    29.          
    30.        private void setTextColorUseReflection(int color) {  
    31.            Field textColorField;  
    32.     try {  
    33.     textColorField = TextView.class.getDeclaredField("mCurTextColor");  
    34.     textColorField.setAccessible(true);  
    35.     textColorField.set(color);  
    36.     textColorField.setAccessible(false);  
    37.     } catch (NoSuchFieldException e) {  
    38.     e.printStackTrace();  
    39.     } catch (IllegalArgumentException e) {  
    40.     e.printStackTrace();  
    41.     } catch (IllegalAccessException e) {  
    42.     e.printStackTrace();  
    43.     }  
    44.            m_TextPaint.setColor(color);  
    45.        }  

            以上代码中m_bDrawSideLine为false即和一般的textView无异,只需要将其改为true即可看到描边效果。以上,我只是抛砖引玉,以下发一个小图吧。

     
     
     
    第三种方法:
    转自:http://bbs.9ria.com/thread-234703-1-1.html
     

    package com.zg.mrcheney;

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Paint.FontMetrics;
    import android.util.AttributeSet;
    import android.widget.TextView;

    public class StrokeText extends TextView {

    private float mBigFontBottom;
    private float mBigFontHeight;

    private String text;
    private Paint mPaint;
    private int strokeSize = 1;

    public StrokeText(Context context) {
    super(context);
    init();
    }

    public StrokeText(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
    }

    public StrokeText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
    }

    private void init() {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setTextSize(getTextSize());
    mPaint.setColor(getResources().getColor(R.color.font_paint_color));
    FontMetrics fm = mPaint.getFontMetrics();
    mBigFontBottom = fm.bottom;
    mBigFontHeight = fm.bottom - fm.top;
    }

    @Override
    protected void onDraw(Canvas canvas) {
    if (strokeSize > 0 && strokeSize < 4) {
    float y = getPaddingTop() + mBigFontHeight - mBigFontBottom;
    canvas.drawText(text, 0, y - strokeSize, mPaint);
    canvas.drawText(text, 0, y + strokeSize, mPaint);
    canvas.drawText(text, 0 + strokeSize, y, mPaint);
    canvas.drawText(text, 0 + strokeSize, y + strokeSize, mPaint);
    canvas.drawText(text, 0 + strokeSize, y - strokeSize, mPaint);
    canvas.drawText(text, 0 - strokeSize, y, mPaint);
    canvas.drawText(text, 0 - strokeSize, y + strokeSize, mPaint);
    canvas.drawText(text, 0 - strokeSize, y - strokeSize, mPaint);
    }

    super.onDraw(canvas);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
    super.setText(text, type);
    this.text = text.toString();
    invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (strokeSize > 0 && strokeSize < 4) {
    setMeasuredDimension(getMeasuredWidth() + strokeSize, getMeasuredHeight());
    }
    }

    }

     
  • 相关阅读:
    Linux getcwd()的实现【转】
    关于__GNU_SOURCE 这个宏---如何开启【转】
    UBI 文件系统移植 sys 设备信息【转】
    Linux USB驱动框架分析【转】
    局部变量、全局变量、堆、堆栈、静态和全局【转】
    C语言字节对齐问题详解【转】
    usb驱动的基本结构和函数简介【转】
    makefile函数集锦【转】
    非常好!!!Linux源代码阅读——内核引导【转】
    JQuery日记6.9 Promise/A之Callbacks
  • 原文地址:https://www.cnblogs.com/cheneasternsun/p/5402632.html
Copyright © 2011-2022 走看看