svg实际使用不多,不知道自己何时注意到的,也在项目中自己使用过。
svg是从Android5.0开始引入的一个drawable的子类VectorDrawable支持矢量图片的,同时还引入了 AnimatedVectorDrawable 来支持矢量图动画,向下兼容到4.0之上。
延续我的风格,先上代码中怎样使用
一、在主工程的build,.gradle中引用
android{
...
defaultConfig {
...
vectorDrawables.useSupportLibrary = true
}
...
}
dependencies {
...
compile "com.android.support:appcompat-v7:21+" // 至少Api21
//下面这句可以不使用
// implementation 'com.android.support:animated-vector-drawable:27.0.2'
...
}
二、项目的Activity
中都包含(通用做法是在BaseActivity中加):
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 加载svg图片使用,activity必须AppCompatActivity
*/
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
...
...
}
三、使用svg图片
1.可以和加载一般图片时使用
2.不过和AppCompat系列控件更配吆,AppCompatImageView没有特别说明
但是在5.0以下的AppCompatTextView可能存在问题的,AppCompatTextView
是没有对CompoundDrawable
进行适配的,所以需要自己动手才能丰衣足食。我们一般使用一个自定义的VectorCompatTextView加载svg图片
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.content.res.AppCompatResources;
import android.support.v7.widget.AppCompatCheckedTextView;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import com.demo.R;
/**
* @author hahaliu
* @version 1.0
* @date 2018/8/16
* @Description textview显示svg中,针对5.0以下有可能出现bug使用的
* 应用tagSdk大于5.0一般的textview使用就可以
*/
public class VectorCompatTextView extends AppCompatCheckedTextView {
private boolean isTintDrawableInTextColor;
private int mDrawableCompatColor;
private boolean isDrawableAdjustTextWidth;
private boolean isDrawableAdjustTextHeight;
private boolean isDrawableAdjustViewWidth;
private boolean isDrawableAdjustViewHeight;
private int mDrawableWidth;
private int mDrawableHeight;
public VectorCompatTextView(Context context) {
this(context, null);
}
public VectorCompatTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VectorCompatTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
}
private void initAttrs(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VectorCompatTextView);
Drawable dl = null;
Drawable dt = null;
Drawable dr = null;
Drawable db = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dl = a.getDrawable(R.styleable.VectorCompatTextView_drawableLeftCompat);
dt = a.getDrawable(R.styleable.VectorCompatTextView_drawableTopCompat);
dr = a.getDrawable(R.styleable.VectorCompatTextView_drawableRightCompat);
db = a.getDrawable(R.styleable.VectorCompatTextView_drawableBottomCompat);
} else {
int dlId = a.getResourceId(R.styleable.VectorCompatTextView_drawableLeftCompat, -1);
int dtId = a.getResourceId(R.styleable.VectorCompatTextView_drawableTopCompat, -1);
int drId = a.getResourceId(R.styleable.VectorCompatTextView_drawableRightCompat, -1);
int dbId = a.getResourceId(R.styleable.VectorCompatTextView_drawableBottomCompat, -1);
if (dlId != -1) {
dl = AppCompatResources.getDrawable(context, dlId);
}
if (dtId != -1) {
dt = AppCompatResources.getDrawable(context, dtId);
}
if (drId != -1) {
dr = AppCompatResources.getDrawable(context, drId);
}
if (dbId != -1) {
db = AppCompatResources.getDrawable(context, dbId);
}
}
isTintDrawableInTextColor = a.getBoolean(R.styleable.VectorCompatTextView_tintDrawableInTextColor, false);
mDrawableCompatColor = a.getColor(R.styleable.VectorCompatTextView_drawableCompatColor, 0);
isDrawableAdjustTextWidth = a.getBoolean(R.styleable.VectorCompatTextView_drawableAdjustTextWidth, false);
isDrawableAdjustTextHeight = a.getBoolean(R.styleable.VectorCompatTextView_drawableAdjustTextHeight, false);
isDrawableAdjustViewWidth = a.getBoolean(R.styleable.VectorCompatTextView_drawableAdjustViewWidth, false);
isDrawableAdjustViewHeight = a.getBoolean(R.styleable.VectorCompatTextView_drawableAdjustViewHeight, false);
mDrawableWidth = a.getDimensionPixelSize(R.styleable.VectorCompatTextView_drawableWidth, 0);
mDrawableHeight = a.getDimensionPixelSize(R.styleable.VectorCompatTextView_drawableHeight, 0);
a.recycle();
if (mDrawableWidth < 0) {
mDrawableWidth = 0;
}
if (mDrawableHeight < 0) {
mDrawableHeight = 0;
}
if (isDrawableAdjustTextWidth) {
isDrawableAdjustViewWidth = false;
}
if (isDrawableAdjustTextHeight) {
isDrawableAdjustViewHeight = false;
}
initDrawables(dl, dt, dr, db);
}
}
private void initDrawables(final Drawable... drawables) {
for (Drawable drawable : drawables) {
tintDrawable(drawable);
}
if (!isDrawableAdjustTextWidth && !isDrawableAdjustTextHeight && !isDrawableAdjustViewWidth &&
!isDrawableAdjustViewHeight && mDrawableWidth == 0 && mDrawableHeight == 0) {
setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], drawables[2], drawables[3]);
} else {
if (isDrawableAdjustTextWidth || isDrawableAdjustTextHeight || isDrawableAdjustViewWidth ||
isDrawableAdjustViewHeight) {
boolean invalid = (
(isDrawableAdjustTextWidth || isDrawableAdjustViewWidth) &&
(drawables[0] != null || drawables[2] != null))
||
((isDrawableAdjustTextHeight || isDrawableAdjustViewHeight)
&& (drawables[1] != null || drawables[3] != null));
if (invalid) {
if (mDrawableWidth > 0 || mDrawableHeight > 0) {
resizeDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
} else {
setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], drawables[2], drawables[3]);
}
} else {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < 16) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
adjustDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
});
}
} else if (mDrawableWidth > 0 || mDrawableHeight > 0) {
resizeDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
}
}
private void tintDrawable(Drawable drawable) {
if (drawable != null) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = DrawableCompat.wrap(drawable).mutate();
}
if (isTintDrawableInTextColor) {
DrawableCompat.setTint(drawable, getCurrentTextColor());
} else if (mDrawableCompatColor != 0) {
DrawableCompat.setTint(drawable, mDrawableCompatColor);
}
}
}
private void resizeDrawables(Drawable... drawables) {
for (Drawable drawable : drawables) {
if (drawable == null) {
continue;
}
if (mDrawableWidth > 0 && mDrawableHeight > 0) {
drawable.setBounds(0, 0, mDrawableWidth, mDrawableHeight);
} else if (mDrawableWidth > 0) {
int h = mDrawableWidth * drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
drawable.setBounds(0, 0, mDrawableWidth, h);
} else {
int w = mDrawableHeight * drawable.getIntrinsicWidth() / drawable.getIntrinsicHeight();
drawable.setBounds(0, 0, w, mDrawableHeight);
}
}
setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
@Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, type);
if (isDrawableAdjustTextWidth || isDrawableAdjustTextHeight) {
Drawable[] drawables = getCompoundDrawables();
if (drawables[0] == null && drawables[1] == null && drawables[2] == null && drawables[3] == null) {
return;
}
adjustDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
}
private void adjustDrawables(Drawable dl, Drawable dt, Drawable dr, Drawable db) {
int width = 0;
int height = 0;
if (isDrawableAdjustTextWidth) {
Paint paint = new Paint();
paint.setTextSize(getTextSize());
CharSequence text = getText();
Rect rect = new Rect();
paint.getTextBounds(text.toString(), 0, text.length(), rect);
width = rect.width();
} else if (isDrawableAdjustViewWidth) {
width = getMeasuredWidth();
}
if (isDrawableAdjustTextHeight) {
Paint paint = new Paint();
paint.setTextSize(getTextSize());
CharSequence text = getText();
Rect rect = new Rect();
paint.getTextBounds(text.toString(), 0, text.length(), rect);
height = rect.height();
} else if (isDrawableAdjustViewHeight) {
height = getMeasuredHeight();
}
int h = mDrawableHeight;
int w = mDrawableWidth;
if (dt != null) {
if (h == 0) {
h = width * dt.getIntrinsicHeight() / dt.getIntrinsicWidth();
}
dt.setBounds(0, 0, width, h);
}
if (db != null) {
if (h == 0) {
h = width * db.getIntrinsicHeight() / db.getIntrinsicWidth();
}
db.setBounds(0, 0, width, h);
}
if (dl != null) {
if (w == 0) {
w = height * dl.getIntrinsicWidth() / dl.getIntrinsicHeight();
}
dl.setBounds(0, 0, w, height);
}
if (dr != null) {
if (w == 0) {
w = height * dr.getIntrinsicWidth() / dr.getIntrinsicHeight();
}
dr.setBounds(0, 0, w, height);
}
setCompoundDrawables(dl, dt, dr, db);
}
@Override
public void setTextColor(@ColorInt int color) {
super.setTextColor(color);
refreshCompoundDrawables();
}
private void refreshCompoundDrawables() {
Drawable[] drawables = getCompoundDrawables();
for (Drawable drawable : drawables) {
tintDrawable(drawable);
}
setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
public boolean isTintDrawableInTextColor() {
return isTintDrawableInTextColor;
}
public void setTintDrawableInTextColor(boolean tintDrawableInTextColor) {
if (isTintDrawableInTextColor == tintDrawableInTextColor) {
return;
}
isTintDrawableInTextColor = tintDrawableInTextColor;
refreshCompoundDrawables();
}
public int getDrawableCompatColor() {
return mDrawableCompatColor;
}
public void setDrawableCompatColor(@ColorInt int drawableCompatColor) {
if (mDrawableCompatColor == drawableCompatColor) {
return;
}
mDrawableCompatColor = drawableCompatColor;
refreshCompoundDrawables();
}
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
Drawable[] drawables = getCompoundDrawables();
initDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
@Override
public void toggle() {
super.toggle();
Drawable[] drawables = getCompoundDrawables();
initDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (isTintDrawableInTextColor) {
Drawable[] drawables = getCompoundDrawables();
boolean needRefresh = false;
for (Drawable drawable : drawables) {
if (drawable != null) {
needRefresh = true;
break;
}
}
if (needRefresh) {
refreshCompoundDrawables();
}
}
}
}
特别注意:自定义控件要在src的value文件中定义attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="VectorCompatTextView">
<attr name="drawableLeftCompat" format="reference"/>
<attr name="drawableRightCompat" format="reference"/>
<attr name="drawableTopCompat" format="reference"/>
<attr name="drawableBottomCompat" format="reference"/>
<attr name="tintDrawableInTextColor" format="boolean"/>
<attr name="drawableCompatColor" format="color|reference"/>
<attr name="drawableAdjustTextWidth" format="boolean"/>
<attr name="drawableAdjustTextHeight" format="boolean"/>
<attr name="drawableAdjustViewWidth" format="boolean"/>
<attr name="drawableAdjustViewHeight" format="boolean"/>
<attr name="drawableWidth" format="dimension|reference"/>
<attr name="drawableHeight" format="dimension|reference"/>
</declare-styleable>
</resources>
3.VectorDrawable转换Bitmap
Bitmap bitmap;
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){
Drawable vectorDrawable = context.getDrawable(R.id.img_vector);
bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
}else {
Drawable drawable = AppCompatDrawableManager.get().getDrawable(context, R.id.img_vector);
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
四、svg图片引入到项目中
1.svg图片可以在阿里矢量图中自己下载图标,也可以安装Android studio的插件、将一般图片转换为svg图片,还可以使用第三工具转换图片格式,这个自行百度,,,
2.引入项目中得操作:res---drawable---new---Vector Asset,然后弹窗选择中选中svg图片
可以基本使用了,有时间的话,日后研究一下svg动画,这个毕竟还是挺嗨皮的、比一般动画居然好玩多了!
参考文章:https://blog.youkuaiyun.com/dick_zeng/article/details/72473591