Document for rule VectorRaster

118 views
Skip to first unread message

Lin Wang

unread,
Nov 2, 2017, 11:58:31 AM11/2/17
to lint-dev
Recently we encountered a case where the following xml failed to be inflated on 4.x devices but work fine on 5.0 and above.

<com.pinterest.ui.text.PButton
android:id="@+id/open_in_browser_overflow_btn"
style="@style/wrap_view"
android:layout_centerVertical="true"
android:background="@drawable/ic_in_app_browser_ellipsis"
android:layout_marginTop="@dimen/list_cell_padding_topbottom"
brio:layout_marginLeft="gStart"
android:visibility="gone" />

We found the root cause if @drawable/ic_in_app_browser_ellipsis is a vector drawable, unlike in ImageView where we could use app:scrCompat to indicate the inflator to deal with the vector drawable
differently on platforms. It's just crashed inside the inflator. The solution is to load the vector drawable with ContextCompat.getDrawablein the code.

But we are wondering if the lint rule VectorRaster is able to catch this case and warn us beforehand and if there is another rule to flag such a use case. Or we'd need to write a custom rule for it.

<ImageView
android:id="@+id/board_sections_iv"
android:layout_height="@dimen/board_picker_section_image_height"
android:layout_width="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:contentDescription="@string/icon_search_more"
app:srcCompat="@drawable/ic_forward_arrow"
brio:layout_marginLeft="2bt"/>

Tor Norbye

unread,
Nov 10, 2017, 11:58:47 AM11/10/17
to lint-dev
Somebody was just mentioning this the other day, and yes, we should add a built-in lint check for this since it affects everybody.

If I understand the issue correctly, what we need to do is:
(1) Look for calls to resources.getDrawable(), and whenever we see those, suggest the user switch to ContextCompat.getDrawable instead, unless
(2) we know what drawable you're inflating (e.g. we can map the resource id being passed into getDrawable back to a R.drawable.name), and can see that it's not a vector drawable, or
(3) the project is not using appcompat, or
(4) the project has no vector drawable, or
(5) the minSdkVersion is high enough for the project that vectors are fully supported (e.g. 21/22 depending on whether the vector is using resources)

Right?

I've filed issue https://issuetracker.google.com/69159933 to track this.

-- Tor

Lin Wang

unread,
Nov 10, 2017, 1:13:46 PM11/10/17
to lint-dev
Also in xml, if you see android:background="@drawable/ic_in_app_browser_ellipsis" and you know this drawable is a vector drawable, then warn the user this will not work if SDK < 5.0.

Btw, is there an app:backgroundCompat that we can use?

Niklas Baudy

unread,
Nov 12, 2017, 7:11:51 AM11/12/17
to lint-dev
I also got bitten by this in a custom view with the following code in my custom view:

icon.setImageDrawable(a.getDrawable(R.styleable.LanguageEntryView_icon))

When using Vector Drawables in the app:icon, above KitKat everything worked but then on KitKat it crashed. I had to replace the above call with:

icon.setImageDrawable(VectorDrawableCompat.create(resources, a.getResourceId(R.styleable.LanguageEntryView_icon, 0), context.theme))

Note that even ContextCompat.getDrawable() didn't work. I had to use VectorDrawableCompat here.

Niklas Baudy

unread,
Nov 12, 2017, 2:52:23 PM11/12/17
to lint-dev
I also just watched the Vector Workflow talk from Nick and it seems like using VectorDrawableCompat.create should not be used instead AppCompatResources.getDrawable is the preferred way. Source. This would make a pretty good lint check too.
Reply all
Reply to author
Forward
0 new messages