Android चयनकर्ता वेक्टरड्रैबल्स के साथ ड्रा करने योग्य srcCompat




vector android-support-library (3)

मैं वेक्टरड्रॉल के साथ नए पिछड़े संगतता के साथ एक समस्या का सामना कर रहा हूं। सपोर्ट लाइब्रेरी में 23.2 एंड्रॉइड वेक्टरड्रॉल के साथ पिछड़ी संगतता के लिए एक नई सुविधा थी।

मेरे पास एक ImageView है जो चयनकर्ता को सौंपा गया है। यह ड्राएबल कई वेक्टरड्रॉल रखता है इसलिए मैंने सोचा कि मुझे संगतता के लिए ऐप: srcCompat का उपयोग करना चाहिए। लेकिन यह एंड्रॉइड 4.1.2 के साथ मेरे गैलेक्सी एस 2 पर काम नहीं करता है।

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_gps_fixed_24dp"android:state_activated="true" android:state_selected="true"></item>
    <item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="true" android:state_selected="false"></item>
    <item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="false" android:state_selected="true"></item>
    <item android:drawable="@drawable/ic_gps_off_24dp" android:state_activated="false" android:state_selected="false"></item>
    <item android:drawable="@drawable/ic_gps_not_fixed_24dp"></item>
</selector>

सभी ड्रॉवल वेक्टर xml फाइलें हैं।

इस चयनकर्ता का उपयोग करते समय srcCompat के साथ मुझे यह त्रुटि मिलती है:

  Caused by: android.content.res.Resources$NotFoundException: File res/drawable/  Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_gps_fixed_24dp.xml from drawable resource ID #0x7f0201c1
                                                                           at android.content.res.Resources.loadDrawable(Resources.java:1951)
                                                                           at android.content.res.Resources.getDrawable(Resources.java:672)
                                                                           at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
                                                                           at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881).xml from drawable resource ID #0x7f0201c1

एंड्रॉइड का उपयोग करना: src भी बदतर है।

अगर मैं ऐप के साथ वेक्टर ड्रॉबल्स में से एक का उपयोग करता हूं: srcCompat सभी ठीक काम करता है। इसलिए मुझे लगता है कि यह SelectorDrawable और संगतता के साथ एक समस्या है।

किसी को भी एक ही समस्या थी और एक समाधान मिल गया है या यह वर्तमान में Android 5 से पहले SelectorDrawables में VectorDrawables का उपयोग करना संभव नहीं है?

त्वरित तथ्य:

  • संकलन लक्ष्य एपीआई 23
  • समर्थन लाइब्रेर 23.3.0
  • VectorDrawables.useSupportLibrary = true
  • गाद २.०

कुछ चीजें बदल गई हैं क्योंकि मैंने यह सवाल पूछा है इसलिए मैं इसका जवाब खुद दूंगा।

समर्थन लाइब्रेरी 23.4.0 के साथ रीसोर्स से वेक्टरड्रैबल्स के लिए समर्थन को फिर से सक्रिय किया गया था: Android समर्थन लाइब्रेरी 23.4.0 अभी उपलब्ध

आप Google I / O 2016 से इस कास्ट के बारे में अधिक जानकारी प्राप्त कर सकते हैं: समर्थन लाइब्रेरी में नया क्या है - Google I / O 2016

आपको इसे हर उस गतिविधि में जोड़ना होगा जहाँ आप Android 5.0 (कोडेन लॉलीपॉप, एपीआई स्तर 21) से नीचे के उपकरणों पर वेक्टरड्राइव का उपयोग करना चाहते हैं:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

तो आप अब ड्राडेबल कॉन्टैक्टर्स में वेक्टरड्रॉवल का उपयोग कर सकते हैं लेकिन यह अभी भी कुछ मुद्दों का कारण बन सकता है जैसा कि ऊपर दिए गए स्रोतों में बताया गया है इसलिए सावधानी के साथ इसका उपयोग करें।

मैंने अभी तक अपने ऐप में इस सुविधा को फिर से शामिल नहीं किया है, लेकिन मैं अपने अगले प्रमुख रिलीज़ के साथ अपने बहुत सारे आइकनों को वेक्टरड्रॉबल्स में बदल दूंगा और फिर इस विषय में गहराई से जान डालूँगा।


जैसा कि @Jahnold ने प्रश्न के लिए टिप्पणी में उल्लेख किया है, एक xml राज्य xml सूची से वेक्टर को लोड करने के लिए समर्थन को 23.3 में हटा दिया गया था।

हालांकि, मुझे कई दृष्टिकोण मिले जो मदद कर सकते हैं।

1. टिंट का उपयोग करना

दृष्टिकोण उपयुक्त है यदि चयनित राज्य सूची से ड्रॉवल केवल रंगों द्वारा अंतर करते हैं।

सबसे पहले, टिंट और सफेद fillColor साथ केवल एक वेक्टर fillColor :

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tintMode="multiply"
    android:tint="@color/button_tint">

    <path
        android:fillColor="#ffffff"
        android:pathData="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>

    <path
        android:pathData="M0 0h24v24H0z"/>

</vector>

दूसरा, res/color में रखा कलर स्टेट लिस्ट button_tint.xml बनाएं

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#555555" android:state_enabled="false"/>
    <item android:color="#6699dd"/>
</selector>

build.gradle लिए फॉलो लाइन्स जोड़ना न भूलें या पुराने एंड्रॉइड वर्जन पर एप्रोच काम नहीं करेगा।

defaultConfig {
    vectorDrawables.useSupportLibrary = true
}

2. StateListDrawable का निर्माण

दृष्टिकोण उपयुक्त है यदि आप राज्य सूची वेक्टर ड्रॉबल्स के लिए उपयोग करते हैं जो न केवल एक रंग, बल्कि एक आंकड़े से भी भिन्न होता है, इसलिए आपको कई अलग-अलग xml फाइलें बनाने की आवश्यकता होती है। फिर आप StateListDrawable प्रोग्राम को एक answer में दिखाए अनुसार बना सकते हैं।


सहायता पुस्तकालय में नया क्या है - Google I / O 2016 देखने के बाद मैंने AppCompatResources वर्ग में एक उपयोगी विधि देखी। यह AppCompatResources#getColorStateList(Context context, int resId) । इस विधि की मदद से मैंने चयनकर्ता को वेक्टर ड्रॉबल्स के साथ लागू किया है। यहाँ मेरा रंग चयनकर्ता फ़ाइल icon_selector :

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/red_selected" android:state_selected="true"/>
    <item android:color="@color/red_pressed" android:state_pressed="true"/>
    <item android:color="@color/red"/>
</selector>

और जावा विधि है जो टिंटेड ड्रॉबल रिटर्न करती है:

private Drawable getTintedDrawable(@DrawableRes int drawableId) {
    Drawable drawable;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        drawable = getResources().getDrawable(drawableId, getTheme());
    } else {
        drawable = getResources().getDrawable(drawableId);
    }
    drawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTintList(drawable.mutate(), AppCompatResources.getColorStateList(this, R.color.selector_nav_bar_item_ico));
    return drawable;
}

आप इसे नीचे दिखाए गए की तरह उपयोग कर सकते हैं

yourImageView.setImageDrawable(getTintedDrawable(R.drawable.ic_vector_image));





android-vectordrawable