如何使用SVG而不是PNG实现Android启动画面?

16

我制作RN应用程序。对于Android版本,我已经创建了/drawable/splash_screen.xml文件,并包含以下内容

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <item
    android:drawable="@color/gray"/>

  <item>
    <bitmap
      android:gravity="center"
      android:src="@mipmap/ic_launcher"/>
  </item>

</layer-list>

并在res/values/styles.xml中链接到此文件。

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_screen</item>
</style>

同样也需要在AndoirdManifest.xml文件中进行配置

<application
  android:name=".MainApplication"
  android:allowBackup="true"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:theme="@style/AppTheme">
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/SplashTheme"
    android:screenOrientation="landscape"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>
  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

这个方案很好,但我想制作SVG文件而不是PNG(mipmap/ic_launcher)。 SVF文件可能像这样 https://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html (至少没有动画)。 如何实现这一点?


我尝试使用可缩放的drawable,但它的默认级别为0,无法在drawable xml中设置。这很遗憾,因为它本来是解决方案。 <scale android:drawable="@drawable/somesvg" android:scaleGravity="center_vertical|fill_horizontal" android:scaleHeight="100%" android:scaleWidth="80%" /> - Softlion
4个回答

29
Android Studio自带的SVG导入器效果不太好,建议使用类似于svg2android的SVG到VectorDrawable转换器。现在我们需要使用由svg2android生成的代码创建可绘制文件。请前往“res/drawable”→新建→可绘制资源文件→将向量代码粘贴到此处。然后,在splash_screen.xml中,我们需要添加一个项目,将我们的矢量图作为可绘制项,并将重心设置为居中。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- background with solid color -->
    <item android:drawable="@android:color/white"/>

    <!-- logo -->
    <item
        android:drawable="@drawable/your_logo"
        android:gravity="center"/>

</layer-list>

-- 2019年12月编辑 --

正如评论中@petyr所指出的那样,svg2android现在已经过时了,但是正如@Krisztián建议的那样,Respresso Image Converter可以完成几乎所有svg2android能做的事情。 只需将SVG图像添加到其中,将其保留为auto,它就会生成一个与Android兼容的SVG。


2
工具svg2android已被弃用。 - petyr
@KrisztiánVelez 但是这个Respresso图像转换器没有相同的功能:不兼容SVG > to > Android兼容SVG。这就是svg2android的魔力所在。 - Nícolas Schirmer
@petyr 你可以使用Android Studio内置的矢量资源,或者仍然使用svg2android。如果有更好的替代方案,我会编辑帖子并添加它 :) - Nícolas Schirmer
@NícolasSchirmer 尝试使用“auto”选项。它会在可能的情况下生成矢量图像。如果您上传了SVG文件,它将返回Android Drawable。它被称为“auto”,因为它可以根据您上传的图像(SVG、PNG、JPEG、PDF、Android Drawable)选择最佳选项。如果您需要特定格式,则可以选择其他选项。Android Drawable未列出,因为它无法从PNG图像中生成,因此无法强制执行。 - Krisztián Velez
2
2021年起,Represso不再为Android提供SVG转换。 - user1034912
显示剩余4条评论

7
在xml文件中,您只需要使用属性drawable而不是bitmap标签。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <item android:drawable="@color/gray"/>

  <item android:drawable="@mipmap/ic_launcher"/>

</layer-list>

那我需要把我的SVG放到每个mipmap-Xdpi文件夹中吗? - CodeBy
不一定,您可以使用资产导入工具导入一个SVG文件。 - rockbass2560
谢谢,我一直在探索互联网,直到我得到这个答案才解决了问题。 - icgoogo

1
首先将其转换为XML格式,然后在SVG中对受控元素进行命名(VectorDrawable)android_svg.xml:
   <vector android:height="400dp" android:viewportHeight="206.132".....>
   ...............
    <path android:name = "arrow"
        android:fillColor="#00000000"
        android:pathData="M 47.30268,56.147897 37.688314,45.379807"
        android:strokeAlpha="1" android:strokeColor="#151414"
        android:strokeLineCap="butt" android:strokeLineJoin="miter" android:strokeWidth="1"/>
   </vector>

使用AnimatedVectorDrawable的第三种方法来对VectorDrawable进行动画:

 <animated-vector
        xmlns:android="http://schemas.android.com/apk/res/android"
        ............................>
    <target android:name="arrow">
        <aapt:attr name="android:animation">
            <set android:ordering="sequentially">
                <objectAnimator
                    android:duration="1000"
                    android:propertyName="pathData"
                    android:valueFrom="M 47.30268,56.147897 37.688314,45.379807"
                    android:valueTo=  "M 47.30268,56.147897 37.688314,45.379807"
                    android:valueType="pathType"
                    tools:targetApi="lollipop" />
                <objectAnimator
                    android:duration="1000"
                    android:propertyName="pathData"
                    android:valueFrom="M 47.30268,56.147897 37.688314,45.379807"
                    android:valueTo=  "M 47.30268,56.147897 57.686195,45.187519"
                    android:valueType="pathType"
                    tools:targetApi="lollipop" />
            </set>

        </aapt:attr>
    </target>
</animated-vector>

这里有一篇关于如何使用上述技术的描述:https://www.ap-impulse.com/animaciya-svg-dlya-web-i-android-splash-screen-shag-105/。以下是相关项目本身:https://github.com/nik137/Diagnostics

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

-5

嗨,你可以按照以下步骤将你的 SVG 文件导入到项目中:

  1. 在Android Studio中右键单击drawable文件夹。
  2. 选择新建 > 矢量图形 > 本地文件
  3. 导入文件后,将复制到drawable文件夹中。
  4. 现在您可以像这样引用drawable

    <item
        android:drawable="@color/off_white"/>
    
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/yoursvg"/>
    </item>
    

完成后,您应该能够在屏幕上看到您的图像。如果有帮助,请测试并接受它作为答案。


1
很不幸,这个不起作用。应用程序在启动时崩溃(弹出消息:“Myapp已停止”)。我已经尝试使用AnimatedVectorDrawable的svg和我的svg文件。 - CodeBy
在你测试的设备上,如果它低于Lolipop版本,那么你应该在build.gradle文件中添加这一行:vectorDrawables.useSupportLibrary = true。 - Sid
我使用Android 5.0+。 - CodeBy
1
一个向量不是位图,因此它不能在位图标签中加载。 - Softlion
这个不行,drawable文件夹不能包含svg文件,只能是xml和png。 - jorgevasquezang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接