Is it possible to create a VectorDrawable from File System (*.xml File)

痞子三分冷 提交于 2020-01-22 19:50:47

问题


I am trying to use VectorDrawables in my Android App.
I want to load an xml File from the File System and get an Instance of android.graphics.Drawable to display it in an ImageView. If i add the xml File to the Resources directory it works. But when i try to load it from the filesystem i always get a NullPointer.

I am currently trying to load the File via Drawable.createFromPath(*Path to File*) or VectorDrawable.createFromPath(*Path to File*), but i keep getting a NullPointer. The File exists and is a valid xml File (see below).

In adb log i always get :

SkImageDecoder::Factory returned null

When i use mContext.getFilesDir() the Path looks something like

/data/data/*packagename*/files/*filename*.xml

I also tried some public Folders like "Downloads". When i check the File with the File.io Api it exists(), canRead() and canWrite()

Update This ist the XML Code taken from the android Dev Pages

 <vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:height="64dp"
 android:width="64dp"
 android:viewportHeight="600"
 android:viewportWidth="600" >
 <group
     android:name="rotationGroup"
     android:pivotX="300.0"
     android:pivotY="300.0"
     android:rotation="45.0" >
     <path
         android:name="v"
         android:fillColor="#000000"
         android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
 </group>


回答1:


Unfortunately, no. Not unless you somehow compile the XML source file in the way that resources are compiled. VectorDrawable currently assumes a compiled image source.

Otherwise you could probably have written something like this:

VectorDrawable d = new VectorDrawable();
try( InputStream in = new FileInputStream( *Path to File* ); )
{
    XmlPullParser p = Xml.newPullParser();
    p.setInput( in, /*encoding, self detect*/null );
    d.inflate( getResources(), p, Xml.asAttributeSet(p) ); // FAILS
}

Currently that fails (API level 23, Marshmallow 6.0) because the inflate call attempts to cast the attribute set to an XmlBlock.Parser, which throws a ClassCastException. The cause is documented in the source; it will “only work with compiled XML files”, such as resources packaged by the aapt tool.




回答2:


Actually, yes you can, and I've done it in my own projects.

As mentioned in the previous answer though, you indeed need the compiled version of the XML drawable instead of the one you get from, say, Android Studio. AFAIK, the VectorDrawable API does not yet support loading from raw XML.

To do this, simply place your images temporarily under the res directory so that they get compiled as normal resources during the build process, then find your generated APK and extract them from there (you'll notice they're no longer text files, but binary files). Now put them again wherever you want under your assets dir and use code similar to this to load them as drawables:

XmlResourceParser parser = context.getAssets()
    .openXmlResourceParser("assets/folder/image.xml");
drawable = VectorDrawableCompat.createFromXml(context.getResources(), parser);

Notice the 'assets/' part of the path. That's required, afaik.



来源:https://stackoverflow.com/questions/32588418/is-it-possible-to-create-a-vectordrawable-from-file-system-xml-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!