IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android中到底支持SVG哪些标签 -> 正文阅读

[移动开发]android中到底支持SVG哪些标签

背景介绍

我们都知道android中支持svg图片,但是到底支持到什么程度,哪些支持哪些不支持,这个问题最近让我反思了起来

根据经验来讲,android中是支持path,group等标签的,但是这两天在通过android studio转换svg成xml的时候遇到了一系列的问题,从png转换的svg图片在转换Vector Asset的时候无法转化,报错,不支持image等标签.

之前确实没有遇到过这个问题,于是在论坛上查了很多博客,但是没有一篇文章能说出来到底不支持哪些标签,支持哪些标签的(也有可能是我没找到),于是放弃吃现成的,准备手撕源码解决,不就是一个xml转换成VectorDrawable吧,无外乎就是xml解析转换,只要找到它解析什么标签,那不解析的不是自动就不支持了吗.说撕就撕.

注: 本文仅仅为了解决支持标签问题,所以对于VectorDrawable整体的绘制流程不阐述,代码也很少,如果有兴趣可以自行梳理.

另:VectorDrawable的类注释其实已经把大概的内容都交代的差不多了,java的javadoc做的还是很nice的,如果想要直接看官方解析,可以直接查看类注释.

VectorDrawable简介

说白了就是一个drawable就是展示图片用的,继承自Drawable,Drawable也很简单,就是一个抽象类,里面会实现一些常用的如Bounds,配置,方向,alpha值,tint着色等参数的配置.

使用时通过使用VectorDrawableCompat中保存的代理mDelegateDrawable实现

源码分析

定位过程忽略,直接上分析

Let‘s go~!

我们在Drawable中可以找到这么一个方法createFromXml

// Drawable.java

// Create a drawable from an XML document.
public static Drawable createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser)
        throws XmlPullParserException, IOException {
    return createFromXml(r, parser, null);
}

可以看到注释的意思就是通过xml文件创建一个drawable对象, 所以这个方法我们也需要看一下

// Drawable.java

// createXml最终会调用到这个方法中
static Drawable createFromXmlInnerForDensity(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, int density, @Nullable Theme theme) throws XmlPullParserException, IOException {
	// r.getDrawableInflater()方法返回的是DrawableInflater.java对象
    return r.getDrawableInflater().inflateFromXmlForDensity(parser.getName(), parser, attrs,
            density, theme);
}

// DrawableInflater.java
Drawable inflateFromXmlForDensity(@NonNull String name, @NonNull XmlPullParser parser,
                                  @NonNull AttributeSet attrs, int density, @Nullable Theme theme)
        throws XmlPullParserException, IOException {
    ...
	// 根据tag查找drawable的具体类型
    Drawable drawable = inflateFromTag(name);
    if (drawable == null) {
        drawable = inflateFromClass(name);
    }
	// 多态调用具体drawable的inflate()方法
    drawable.inflate(mRes, parser, attrs, theme);
    return drawable;
}

// 这里就是我们希望看到各种drawable的xml解析了
private Drawable inflateFromTag(@NonNull String name) {
    switch (name) {
        case "selector":
            return new StateListDrawable();
        case "animated-selector":
            return new AnimatedStateListDrawable();
        case "level-list":
            return new LevelListDrawable();
        case "layer-list":
            return new LayerDrawable();
        case "transition":
            return new TransitionDrawable();
        case "ripple":
            return new RippleDrawable();
        case "adaptive-icon":
            return new AdaptiveIconDrawable();
        case "color":
            return new ColorDrawable();
        case "shape":
            return new GradientDrawable();
        case "vector":
            return new VectorDrawable();
        case "animated-vector":
            return new AnimatedVectorDrawable();
        case "scale":
            return new ScaleDrawable();
        case "clip":
            return new ClipDrawable();
        case "rotate":
            return new RotateDrawable();
        case "animated-rotate":
            return new AnimatedRotateDrawable();
        case "animation-list":
            return new AnimationDrawable();
        case "inset":
            return new InsetDrawable();
        case "bitmap":
            return new BitmapDrawable();
        case "nine-patch":
            return new NinePatchDrawable();
        case "animated-image":
            return new AnimatedImageDrawable();
        default:
            return null;
    }
}

// VectorDrawable.java
public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
        @NonNull AttributeSet attrs, @Nullable Theme theme)
        throws XmlPullParserException, IOException {
    try {
        ...
        inflateChildElements(r, parser, attrs, theme);
		...
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
    }
}

private void inflateChildElements(Resources res, XmlPullParser parser, AttributeSet attrs,
                                  Theme theme) throws XmlPullParserException, IOException {
    final VectorDrawableState state = mVectorState;
    boolean noPathTag = true;

    // Use a stack to help to build the group tree.
    // The top of the stack is always the current group.
	// 注释说明的很清楚, 栈就是用来构建节点树结构的
    final Stack<VGroup> groupStack = new Stack<VGroup>();
    groupStack.push(state.mRootGroup);

    int eventType = parser.getEventType();
    final int innerDepth = parser.getDepth() + 1;

    // Parse everything until the end of the vector element.
    while (eventType != XmlPullParser.END_DOCUMENT
            && (parser.getDepth() >= innerDepth || eventType != XmlPullParser.END_TAG)) {
        if (eventType == XmlPullParser.START_TAG) {
            final String tagName = parser.getName();
            final VGroup currentGroup = groupStack.peek();

			// <path>节点
            if (SHAPE_PATH.equals(tagName)) {
                final VFullPath path = new VFullPath();
                path.inflate(res, attrs, theme);
                currentGroup.addChild(path);
                if (path.getPathName() != null) {
                    state.mVGTargetsMap.put(path.getPathName(), path);
                }
                noPathTag = false;
                state.mChangingConfigurations |= path.mChangingConfigurations;
			// <clip-path>节点
            } else if (SHAPE_CLIP_PATH.equals(tagName)) {
                final VClipPath path = new VClipPath();
                path.inflate(res, attrs, theme);
                currentGroup.addChild(path);
                if (path.getPathName() != null) {
                    state.mVGTargetsMap.put(path.getPathName(), path);
                }
                state.mChangingConfigurations |= path.mChangingConfigurations;
			// <group>节点
            } else if (SHAPE_GROUP.equals(tagName)) {
                VGroup newChildGroup = new VGroup();
                newChildGroup.inflate(res, attrs, theme);
                currentGroup.addChild(newChildGroup);
                groupStack.push(newChildGroup);
                if (newChildGroup.getGroupName() != null) {
                    state.mVGTargetsMap.put(newChildGroup.getGroupName(),
                            newChildGroup);
                }
                state.mChangingConfigurations |= newChildGroup.mChangingConfigurations;
            }
        } else if (eventType == XmlPullParser.END_TAG) {
            final String tagName = parser.getName();
            if (SHAPE_GROUP.equals(tagName)) {
                groupStack.pop();
            }
        }
        eventType = parser.next();
    }

    if (noPathTag) {
        final StringBuffer tag = new StringBuffer();

        if (tag.length() > 0) {
            tag.append(" or ");
        }
        tag.append(SHAPE_PATH);

        throw new XmlPullParserException("no " + tag + " defined");
    }
}

到这里我们就知道了 VectorDrawable支持path, clip-path和group.当然 这个只是简单的解析,至于xml中的动画 渐变色这些通用标签VectorDrawable应该也是支持的, 如果后续有需要再查找那些标签在哪里调用,在哪里支持的

由于图片处理所以涉及到很多的内部机制以及jni的调用,具体的精髓还是应该在jni中的native方法,慢慢学习

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:41:04  更:2022-03-12 17:41:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 18:27:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码