构建时PNG生成不支持对其他资源的引用

时间:2017-10-27 15:27:55

标签: android resources android-studio-3.0

AndroidStudio 3.0 / Android Gradle插件3.0

<vector>
  <path android:fillColor="@color/image_button_disabled"/>
</vector>

我收到此错误:

  

构建时PNG生成不支持对其他资源的引用

是否可以解决它或者它是一个弃用的解决方案?

9 个答案:

答案 0 :(得分:231)

在您的应用build.gradle中添加以下内容:

defaultConfig{
   vectorDrawables.useSupportLibrary = true
}

有关详细信息,请参阅Android Developers: Vector Drawables Backward Compatibility Solution

答案 1 :(得分:10)

您需要直接使用十六进制代码而不是引用资源。

<vector
  <path
    android:fillColor="#FFF"/></vector>

答案 2 :(得分:7)

此错误的更多背景信息:

  • Android 5.0(API级别21)是第一个正式支持矢量可绘制对象的版本。
  • 如果您使用的minSdkVersion低于20,则有两种可绘制矢量的解决方案
    • Android Studio的Vector Asset Studio生成PNG。请看看Android Studio document。但是,生成时PNG生成不支持对其他资源的引用。
    • 使用支持库
  • 或者,对于minSdkVersion使用21或更高版本

对于支持库,在您的build.gradle文件中添加一条语句:

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  compile 'com.android.support:appcompat-v7:23.2.0'
}

答案 3 :(得分:4)

如果您的minSdkVersion为21,则可以通过添加以下行来禁用PNG的生成:

// set to an empty list to disable the feature
vectorDrawables.generatedDensities = [] 

删除此行仍将生成PNG。

来源: http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.VectorDrawablesOptions.html

答案 4 :(得分:3)

不要在Vector drawable中的fillColor属性中使用colorReference,只需使用hexa代码

像这样使用

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
<path
    android:fillColor="#1abc9c"
    android:pathData="M9,11L7,11v2h2v-2zM13,11h-2v2h2v-2zM17,11h-2v2h2v-2zM19,4h-1L18,2h-2v2L8,4L8,2L6,2v2L5,4c-1.11,0 -1.99,0.9 -1.99,2L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM19,20L5,20L5,9h14v11z"/>

而不是

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
<path
    android:fillColor="@color/colorPrimary"
    android:pathData="M9,11L7,11v2h2v-2zM13,11h-2v2h2v-2zM17,11h-2v2h2v-2zM19,4h-1L18,2h-2v2L8,4L8,2L6,2v2L5,4c-1.11,0 -1.99,0.9 -1.99,2L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM19,20L5,20L5,9h14v11z"/>

答案 5 :(得分:0)

我已经通过以下方式解决了这个问题:

  1. 创建一个drawable-v21文件夹并复制所有使用变量的可绘制xmls
  2. 在原始drawable文件夹中将所有图标更改为使用静态颜色
  3. 这样编译器就可以工作

答案 6 :(得分:0)

我认为您正在使用android:fillColor="@color/image_button_disabled"这个代码来绘制矢量。

// image_button_disabled.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/circular_image_color_pressed" android:state_pressed="true" />
    <item android:color="@color/circular_image_color_normal" />
</selector>

不支持。

只需将其替换为android:fillColor="#c4ca5e"

答案 7 :(得分:0)

最多可添加[over.over]/6 @mwa91

如果需要动态绘制对象,但是没有时间更新布局并使用answer @mwa91并将所有for (int i=0; i < listOfColourNames.length; ++i) { System.out.println(listOfColourNames[i] + " : " + listOfColourCodes[i]); } 属性更改为{{1} },您始终可以在drawable中使用十六进制颜色值,然后在ImageView中为该drawable着色:

android:src="@drawable/..."

答案 8 :(得分:0)

删除filltype,警告就会消失。那是因为:

<块引用>

minSdkVersion 必须是 24 仅当你使用 android:filltype

<块引用>

默认的 fillType 是非零,但它只在某些情况下与 evenOdd 不同

当然,请确保您不需要填充类型。在某些情况下,它可能会影响矢量可绘制对象的外观。如果您的图标很简单,您很可能不需要它。它有时会自动添加,例如当您从 SVG 导入矢量可绘制对象时。

查看此页面以了解其作用w3.org/TR/SVG/painting.html#FillRuleProperty

感谢@Simone 和@hmac


一个简单的替代方法是直接使用颜色值,而不是使用颜色参考。

import java.util.Date;
import java.util.Properties;
import java.util.Set;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.exception.ConnectorException;

public class AdminClientExampleSoap implements NotificationListener {

    private AdminClient adminClient;
    private ObjectName nodeAgent;
    private long ntfyCount = 0;

    public static void main(String[] args) {
        AdminClientExampleSoap ace = new AdminClientExampleSoap();

        // Create an AdminClient
        ace.createAdminClient();

        // Find a NodeAgent MBean
        ace.getNodeAgentMBean("timmieNode07");

        // Invoke launchProcess
        ace.invokeLaunchProcess("server1");

        // Register for NodeAgent events
        ace.registerNotificationListener();

        // Run until interrupted
        ace.countNotifications();
    }

    private void createAdminClient() {
        // Set up a Properties object for the JMX connector attributes
        Properties connectProps = new Properties();
        connectProps.setProperty(AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
        connectProps.setProperty(AdminClient.CONNECTOR_HOST, "x.x.x.x");
        connectProps.setProperty(AdminClient.CONNECTOR_PORT, "8880");
        System.setProperty("com.ibm.SSL.ConfigURL",
                "file:/home/anandatelanakula/eclipse-workspace/wssoap/src/jmx/ibmwebsphere/ssl.client.props");
        System.setProperty("com.ibm.SOAP.ConfigURL",
                "file:/home/anandatelanakula/eclipse-workspace/wssoap/src/jmx/ibmwebsphere/soap.client.props");

        // Get an AdminClient based on the connector properties
        try {
            adminClient = AdminClientFactory.createAdminClient(connectProps);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Exception creating admin client: " + e);
            System.exit(-1);
        }

        System.out.println("Connected to DeploymentManager");
    }

    private void getNodeAgentMBean(String nodeName) {
        // Query for the ObjectName of the NodeAgent MBean on the given node
        try {
            String query = "WebSphere:type=NodeAgent,node=" + nodeName + ",*";
            ObjectName queryName = new ObjectName(query);
            Set s = adminClient.queryNames(queryName, null);
            if (!s.isEmpty())
                nodeAgent = (ObjectName) s.iterator().next();
            else {
                System.out.println("Node agent MBean was not found");
                System.exit(-1);
            }
        } catch (MalformedObjectNameException e) {
            System.out.println(e);
            System.exit(-1);
        } catch (ConnectorException e) {
            System.out.println(e);
            System.exit(-1);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }

        System.out.println("Found NodeAgent MBean for node " + nodeName);
    }

    private void invokeLaunchProcess(String serverName) {
        // Use the launchProcess operation on the NodeAgent MBean to start
        // the given server
        String opName = "launchProcess";
        String signature[] = { "java.lang.String" };
        String params[] = { serverName };
        boolean launched = false;
        try {
            Boolean b = (Boolean) adminClient.invoke(nodeAgent, opName, params, signature);
            launched = b.booleanValue();
            if (launched)
                System.out.println(serverName + " was launched");
            else
                System.out.println(serverName + " was not launched");

        } catch (Exception e) {
            System.out.println("Exception invoking launchProcess: " + e);
        }
    }

    private void registerNotificationListener() {
        // Register this object as a listener for notifications from the
        // NodeAgent MBean. Don't use a filter and don't use a handback
        // object.
        try {
            adminClient.addNotificationListener(nodeAgent, this, null, null);
            System.out.println("Registered for event notifications");
        } catch (InstanceNotFoundException e) {
            System.out.println(e);
        } catch (ConnectorException e) {
            System.out.println(e);
        }
    }

    public void handleNotification(Notification ntfyObj, Object handback) {
        // Each notification that the NodeAgent MBean generates will result in
        // this method being called
        ntfyCount++;
        System.out.println("***************************************************");
        System.out.println("* Notification received at " + new Date().toString());
        System.out.println("* type      = " + ntfyObj.getType());
        System.out.println("* message   = " + ntfyObj.getMessage());
        System.out.println("* source    = " + ntfyObj.getSource());
        System.out.println("* seqNum    = " + Long.toString(ntfyObj.getSequenceNumber()));
        System.out.println("* timeStamp = " + new Date(ntfyObj.getTimeStamp()));
        System.out.println("* userData  = " + ntfyObj.getUserData());
        System.out.println("***************************************************");

    }

    private void countNotifications() {
        // Run until killed
        try {
            while (true) {
                Thread.currentThread().sleep(60000);
                System.out.println(ntfyCount + " notification have been received");
            }
        } catch (InterruptedException e) {
        }
    }

}

另一种选择是设置这个,但我宁愿避免它:

android:fillColor="#FF00AABB" // use this
android:fillColor="@color/image_button_disabled" // instead of this

最后的替代方案是 defaultConfig { vectorDrawables.useSupportLibrary = true }