Egemen Hamutçu
Egemen Hamutçu

Reputation: 1702

Using attr in shape XML causes crash in Android

I have a drawable in this XML:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:endColor="@color/transparent"
        android:gradientRadius="200dp"
        android:startColor="?attr/primaryDarkTransparent"
        android:type="radial" />
</shape>

The XML causes a crash when startColor uses ?attr/primaryDarkTransparent saying:

Caused by: java.lang.RuntimeException: org.xmlpull.v1.XmlPullParserException: <internal><gradient> tag requires 'gradientRadius' attribute with radial type Caused by: org.xmlpull.v1.XmlPullParserException: <internal><gradient> tag requires 'gradientRadius' attribute with radial type

The dramatic story is that it works very well when I use attr in solid and stroke but I don't know what the hell is going on in gradient.

Any advices will be appreciated.

Upvotes: 7

Views: 1214

Answers (3)

Alex Behemoth
Alex Behemoth

Reputation: 21

Problem is using attrubutes: android:startColor="?attr/primaryDarkTransparent" This leads to crash on android < 10 version. Just use link @color/.. or exact color #102010

Upvotes: 0

MatJB
MatJB

Reputation: 145

Workaround for a gradient from some color (could be solid or with some transparency) to the same color with any percentage of transparency.
Note: This is not a complete/general solution to the problem as the result will only have one color and it is applied to an ImageView (although it can be used in other types of Views).
Tested: From API 31 down to 24.

Steps:
Create a shape with a gradient from some color with any percentage of transparency (black, for example, it doesn't matter which, it will be overridden later) into the same color with another percentage of transparency.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:type="radial"
        android:gradientRadius="115%"
        android:centerX="1"
        android:centerY="1"
        android:startColor="#fe000000"
        android:centerColor="#f0000000"
        android:endColor="#50000000" />
    <corners
        android:topLeftRadius="10dp"/>
</shape>

rounded rectangle shape with transparency

Then, in your ImageView add the following if you need it in the foreground:
This is the place where we use the attr from our theme to override the color we used in the gradient.

    android:foreground="@drawable/rounded_rectangle_with_translucent_gradient"
    android:foregroundTint="?attr/colorSurface"

Or these for the background:

    android:background="@drawable/rounded_rectangle_with_translucent_gradient"
    app:backgroundTint="?attr/colorSurface"

Final result:
Our ImageView over another ImageView and a TextView.

Example of result

Upvotes: 0

Giorgio Antonioli
Giorgio Antonioli

Reputation: 16214

There are two problems in your shape.

  1. Below Android L (API 21) you can't use attributes in custom drawables, so you should replace ?attr/primaryDarkTransparent with a color reference.

  2. The gradientRadius should be a float. E.g. 200

Upvotes: 1

Related Questions