36

我使用的矢量可繪製在android系統棒棒糖,這些都是我的庫和工具之前版本:預碰撞棒棒糖採用了Android矢量繪圖資源

  • Android的工作室:2.0
  • Android的搖籃插件:2.0.0
  • 生成工具:23.0.2
  • Android的支持庫:23.3.0

我在我的應用程序級別添加此屬性Build.Gradle

android { 
    defaultConfig { 
    vectorDrawables.useSupportLibrary = true 
    } 
} 

另外值得一提的是我使用一個額外的繪製,如LayerDrawable(layer_list)作爲Android的官方博客(link here)表示,用於設置之外矢量可繪製可繪製app:srcCompat

<level-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@drawable/search"/> 
</level-list> 

你會發現直接引用 應用程序之外矢量繪圖資源:棒棒糖之前srcCompat將失敗。然而,當AppCompat 在另一個 可繪製容器(如StateListDrawable,InsetDrawable, LayerDrawable,LevelListDrawable和RotateDrawable)中被引用時,它支持加載矢量繪圖。通過使用此 間接,您可以在諸如TextView的 android:drawableLeft屬性的情況下使用矢量繪圖,這通常不會支持矢量繪圖。

當我使用app:srcCompat一切工作正常,但是當我使用:

android:background 
android:drawableLeft 
android:drawableRight 
android:drawableTop 
android:drawableBottom 

ImageViewImageButtonTextViewEditText棒棒糖之前,它拋出一個厚望

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9 
+0

的可能的複製[Android的載體的相容性(http://stackoverflow.com/questions/31870992/android-vector-compatibility) –

+0

要了解如何與drawableLeft使用VectorDrawable, drawableRight,drawableTop,drawableBottom簽出[This answer](http://stackoverflow.com/a/40250753/5079879) –

+0

你能檢查我的答案嗎? http://stackoverflow.com/a/40523623/2557258 – Yazon2006

回答

49

我認爲這是因爲支持向量在最新的庫版本中被禁用:23.3.0

根據這一POST

對於程序兼容性的用戶,我們決定刪除哪些讓你使用矢量繪圖資源從預棒棒糖設備的資源由於在執行中發現的23.2版本問題的功能。 0/23.2.1 (ISSUE 205236)。使用app:srcCompat和setImageResource()繼續工作。

如果您訪問的問題ISSUE 205236,似乎他們將在未來實現,但內存問題不應該被儘快修復:

在下一版本中我已經添加了一個選擇的API,其中您可以重新啓用已刪除的VectorDrawable支持。它與之前的警告一樣(內存使用和配置更新問題)。

我有類似的問題。因此,就我而言,我將所有使用從資源中繪製的矢量的圖標重新還原爲PNG圖像(因爲即使它們提供了一個選項以啓用它,內存問題仍然會發生)。

我不確定這是否是最佳選擇。但它修復了所有崩潰。

UPDATE

他們重新啓用了VectorDrawable在
Android Support Library 23.4.0

對於程序兼容性的用戶,我們添加了一個選擇在 API重新啓用支持向量通過AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)從資源(23.2中的行爲)中繪製出來 - 請記住,這仍然會導致內存使用問題和更新配置實例的問題,因此默認情況下它被禁用。

也許build.gradle設置現在已經過時了,你只需要啓用它在適當的活動(然而,需要測試)。

現在,啓用它,你必須做到:

public class MainActivity extends AppCompatActivity { 
    static { 
     AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 
    } 

    ... 
} 
+0

謝謝@Guilherme P.但你爲什麼沒有去掉'vectorDrawables.useSupportLibrary = true'屬性來重新啓用**在構建時**再次生成pngs? –

+0

哦對不起,如果我不清楚......我沒有從build.gradle中刪除該標記..我的意思是,我從可繪製文件夾中刪除了所有vectors_images.xml並將其替換爲PNG圖標(就像我以前使用的那樣) ...在我的情況下,我使用矢量繪製代替一些圖標...... – W0rmH0le

+0

我知道。但即使沒有來自build.gradle的標籤,前棒棒糖機器人應該能夠使用矢量繪圖在生成時生成PNG?不是嗎? –

22

Guillherme P答案是相當真棒。只需稍作改進,就不需要在每個活動中添加該行,如果您在Application類中添加了一次,它也會起作用。

public class App extends Application { 

static { 
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 
} 

記住:你仍然需要啓用的gradle中使用支持庫:

android { 
    defaultConfig { 
    vectorDrawables.useSupportLibrary = true 
    } 
} 

此外,請確保您使用的是支持庫版本比v23.4更大,當谷歌加回VectorDrawables(release note

注意用於繪製對象容器的支持:反正,我建議使用PNG格式,直到谷歌想出了一個更好的修復,或者您可能有內存問題。

+3

這種方法仍然不適用於drawables。 – cesards

+0

請記住,您需要在gradle中使用矢量繪圖的支持庫:vectorDrawables.useSupportLibrary = true – Benny

+2

是的。我知道。但是有必要使用一個包裝器來使矢量繪製工作爲TexViews的可繪製工作,所以這個答案是不完整的。 – cesards

-1

Benny的答案另一種方法是創建一個Activity超:

public abstract class VectorDrawableActivity extends AppCompatActivity { 
    static { 
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 
    } 

    //... 
} 

現在延長VectorDrawableActivity而不是AppCompatActivity。在預棒棒糖

+1

這種方法仍然無法與drawables一起使用。 – cesards

+0

@cesards爲什麼不呢? –

3

VectorDrawables應該可以正常工作,而無需使用

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 

如果你想使用內部ImageViews VectorDrawables,你可以使用屬性srcCompat,它會工作,但裏面的按鈕或TextViews它韓元」 t,所以您需要將Drawable包裝到InsetDrawable或LayerDrawable中。還有一個竅門,我發現,如果你正在使用數據綁定,你可以這樣做:

android:drawableLeft="@{@drawable/vector_ic_access_time_24px}" 
android:drawableStart="@{@drawable/vector_ic_access_time_24px}" 

這將神奇的工作,我沒有調查發生了什麼幕後,但我猜的TextView使用從AppCompatResources或類似的getDrawable方法。

+0

如何在選擇器中設置矢量圖像? –

+0

不工作 - 20.12.2017 – JohannaNoobie

33

詳細說明另一個very good answers,這裏是a diagram,可以幫助你。如果您的Support Library從23.4.0到至少25.1.0,這是有效的。

VectorDrawable cheatsheet

+1

如果您正在嘗試設置drawableLeft,則將其包裝在drawable中,如上所述。 https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88 –

+0

謝謝這張圖表幫助了我們很多。 – sector11

-2

吉列爾梅普的建議是不是爲我工作。我繼續前進,並決定使用png,我需要在應用程序之外執行任何操作:srcCompat,即drawableLeft,drawableRight等。這是一個非常容易的更改,並且沒有潛在的內存問題AppCompatDelegate.setCompatVectorFromResourcesEnabled(真正); 介紹。

21

我有同樣的問題。 但是做了很多R & D我得到了答案。

對於Imageview和ImageButton,使用app:srcCompat =「@ drawable/....」 和其他視圖,如Button,Textview,而不是在XML中使用「drawableLeft/right ...」,指定drawables編程爲:

button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null); 

並使用「AppCompatResources」來獲取drawable。

+1

它的工作原理!謝謝 –

+0

工程就像一個魅力。這應該是我接受的答案 –

+0

。非常感謝:) –

2

我有同樣的問題。通過去除

vectorDrawables.useSupportLibrary = true 

我的目標版本是25和支持庫修復它是

compile 'com.android.support:appcompat-v7:25.3.1' 
2

我使用的預棒棒糖設備VectorDrawables,這是我要做的事: -

第1步: 將其放入您的應用程序級別gradle中。

android { 
    defaultConfig { 
    vectorDrawables.useSupportLibrary = true 
    } 
} 

第2步:

在你的應用程序類將這個並沒有忘記在manifest文件中註冊您的應用程序類。

public class App extends Application { 
    static { 
     AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); 
    } 
} 

第3步:

使用Get VectorDrawables,

imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable)); 
1

對於任何人誰升級至Android gradle這個3.0及以上,就沒有必要使用AppCompatDelegate.setCompatVectorFromResourcesEnabled(true),或設置vectorDrawables.useSupportLibrary = true(添加這將導致問題),並使用app:srcCompat,它只是工作。

-1

現在有一個更簡單的解決方案,只需從app命名空間使用app:drawableRightCompat即可。

或者風格:

<style name="YourStyle"> 
    <item name="drawableRightCompat">@drawable/your_vector</item> 
</style>