前言
上一篇已經講了如何實現textView中粗字體效果,里面主要重寫了onDraw方法。
這一邊講一個進階功能,實現textView的描邊效果。
上效果圖。
上代碼:
public class StrokeTextView extends TextView { private TextView backGroundText = null;//用於描邊的TextView public StrokeTextView(Context context) { this(context, null); } public StrokeTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StrokeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); backGroundText = new TextView(context, attrs, defStyle); } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { //同步布局參數 backGroundText.setLayoutParams(params); super.setLayoutParams(params); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { CharSequence tt = backGroundText.getText(); //兩個TextView上的文字必須一致 if (tt == null || !tt.equals(this.getText())) { backGroundText.setText(getText()); this.postInvalidate(); } backGroundText.measure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } protected void onLayout(boolean changed, int left, int top, int right, int bottom) { backGroundText.layout(left, top, right, bottom); super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { //其他地方,backGroundText和super的先后順序影響不會很大,但是此處必須要先繪制backGroundText, init(); backGroundText.draw(canvas); super.onDraw(canvas); } public void init() { TextPaint tp1 = backGroundText.getPaint(); //設置描邊寬度 tp1.setStrokeWidth(2); //背景描邊並填充全部 tp1.setStyle(Paint.Style.FILL_AND_STROKE); //設置描邊顏色 backGroundText.setTextColor(Color.parseColor("#1E90FF")); //將背景的文字對齊方式做同步 backGroundText.setGravity(getGravity()); } }
原理講解:
效果實現思路是:因為系統api只給paint設置strokewidth方法,卻沒有提供設置描邊的色值的方法,而且我們通過上一篇博客知道,設置描邊屬性的textview,會比沒有設置描邊屬性的textview粗一點
所以我們可以通過自定義兩個Textview,其中一個有描邊的作為背景TextView,另外一個沒有描邊的細一點的textview作為內容。這樣兩個textview合並在一起,就給人一種有描邊的感覺。
知識點講解:
1、對於需要修改、或者需要封裝自定義控件的小伙伴,可以只針對init進行修改。在里面設置strokewidth寬度,還有textColor就可以了。
2、如果在init方法中,paint的style設置為stroke屬性,則可以這樣寫
@Override protected void onDraw(Canvas canvas) { //其他地方,backGroundText和super的先后順序影響不會很大,但是此處必須要先繪制backGroundText, super.onDraw(canvas); init(); backGroundText.draw(canvas); }
當設置paint的style屬性為stroke時,兩種寫法的區別是,第二種寫法效果的描邊更粗一點。
拓展:文字發光效果
private TextView txt_name;
txt_name.setShadowLayer(12,0,0, Color.WHITE);
– 參數詳解 –
setShadowLayer(float radius, float dx, float dy, int color)
1.radius:模糊半徑,越大越模糊
2.dx:x軸偏移量,陰影離開文字的x橫向距離
3.dy:y軸偏移量,陰影離開文字的Y橫向距離
4.color:陰影顏色