概述
取自https://github.com/m5/MagicTextView,感谢m5
设置一个attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MagicTextView">
<attr name="innerShadowColor" format="color"/>
<attr name="innerShadowRadius" format="float"/>
<attr name="innerShadowDx" format="float"/>
<attr name="innerShadowDy" format="float"/>
<attr name="outerShadowColor" format="color"/>
<attr name="outerShadowRadius" format="float"/>
<attr name="outerShadowDx" format="float"/>
<attr name="outerShadowDy" format="float"/>
<attr name="typeface" format="string" />
<attr name="foreground" format="reference|color"/>
<attr name="background" format="reference|color"/>
<attr name="strokeWidth" format="float" />
<attr name="strokeMiter" format="float" />
<attr name="strokeColor" format="color" />
<attr name="strokeJoinStyle">
<enum name="miter" value="0" />
<enum name="bevel" value="1" />
<enum name="round" value="2" />
</attr>
</declare-styleable>
</resources>
然后自定义我们的TextView类:
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.Pair;
import android.widget.TextView;
import com.carcon.navi.uitools.ScreenMeasure;
import com.carcon.ui.R;
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.setTextAlign(Paint.Align.CENTER);
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;
}
}
}
这类中的描边是内描边,如果要外描边的话
在onDraw里面画完描边字体以后加上
paint.setStrokeWidth(0);
super.onDraw(canvas);
就ok了
调用方发如下:
xml:
<com.qwerjk.better_text.MagicTextView
xmlns:qwerjk="http://schemas.android.com/apk/res/com.qwerjk.better_text"
android:textSize="78dp"
android:textColor="#ff333333"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/btn_star"
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="Sample" />
java:
view = new MagicTextView(context);
view.addInnerShadow(0, -1, 0, 0xFFffffff);
view.addOuterShadow(0, -1, 0, 0xff000000);
view.setStroke(4, 0xFFff0000);
view.setForegroundDrawable(getResources().getDrawable(R.drawable.fake_luxury_tiled);
最后
以上就是还单身大船为你收集整理的外发光、内发光、描边、阴影的TextView的全部内容,希望文章能够帮你解决外发光、内发光、描边、阴影的TextView所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复