क्या Android का उपयोग करके Buttons और TextViews में वेक्टरड्राएबल का उपयोग करना संभव है: DrawableRight?


120

जब मैं एक टेक्स्टव्यू या इमेजव्यू में वेक्टरड्राएबल एसेट्स का उपयोग करता हूं तो मुझे "एंड्रॉइड: ड्राएबलराइट" / "एंड्रॉइड: ड्राएबलएंड" / "एंड्रॉइड: ड्राएबलस्टार्ट" / "एंड्रॉइड: ड्रॉएबलटेफ्ट" का उपयोग करते हुए एक रनटाइम क्रैश मिलता है।

ऐप बिना किसी चेतावनी के ठीक संकलन करेगा।

मै इस्तेमाल कर रहा हूँ

  • गाद १.५
  • समर्थन पुस्तकालय 23.2 ('com.android.support:appcompat-v7:23.2.0')

हालांकि मुझे जो भी मिला है वह यह है कि मैं प्रोग्रामर को इस तरह से क्रैश हुए बिना जावा में SVG का असाइन कर सकता हूं।

TextView tv = (TextView) findViewById(R.id.textView);
tv.setCompoundDrawablesWithIntrinsicBounds(null,null, getResources().getDrawable(R.drawable.ic_accessible_white_36px),null);

(मुझे संदेह है कि यह 23.2 के लिए एक समर्थन लाइब्रेरी बग है।)

लेकिन क्या एसवीजी परिसंपत्तियों के लिए ड्रॉएबल राइट आदि का उपयोग करना संभव है?

यहाँ मेरा लेआउट है

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="au.com.angryitguy.testsvg.MainActivity">


<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@drawable/ic_accessible_white_36px"
    android:background="@color/colorPrimary"
    android:textColor="#FFFFFF"
    android:textSize="22sp"
    android:text="Hello World!"/>
</RelativeLayout>

यहाँ मेरी गतिविधि है

package au.com.angryitguy.testsvg;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        }
    }

यहां Google की सामग्री डिज़ाइन साइट से अनमॉडिफ़र्ड वेक्टर-योग्य संपत्ति है।

<vector android:height="24dp" android:viewportHeight="24.0"
    android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FFFFFF" android:pathData="M12,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
    <path android:fillColor="#FFFFFF" android:pathData="M19,13v-2c-1.54,0.02 -3.09,-0.75 -4.07,-1.83l-1.29,-1.43c-0.17,-0.19 -0.38,-0.34 -0.61,-0.45 -0.01,0 -0.01,-0.01 -0.02,-0.01L13,7.28c-0.35,-0.2 -0.75,-0.3 -1.19,-0.26C10.76,7.11 10,8.04 10,9.09L10,15c0,1.1 0.9,2 2,2h5v5h2v-5.5c0,-1.1 -0.9,-2 -2,-2h-3v-3.45c1.29,1.07 3.25,1.94 5,1.95zM12.83,18c-0.41,1.16 -1.52,2 -2.83,2 -1.66,0 -3,-1.34 -3,-3 0,-1.31 0.84,-2.41 2,-2.83L9,12.1c-2.28,0.46 -4,2.48 -4,4.9 0,2.76 2.24,5 5,5 2.42,0 4.44,-1.72 4.9,-4h-2.07z"/>
</vector>

यहाँ मेरा app build.gradle है

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "au.com.angryitguy.testsvg"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        // Stops the Gradle plugin’s automatic rasterization of vectors
        generatedDensities = []
    }
    // Flag to tell aapt to keep the attribute ids around
    aaptOptions {
        additionalParameters "--no-version-vectors"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
}

यहाँ दुर्घटना है। (टेक्स्टव्यू का संदर्भ देने वाली त्रुटि को नोट करें।)

java.lang.RuntimeException: Unable to start activity ComponentInfo{
    au.com.angryitguy.testsvg/au.com.angryitguy.testsvg.MainActivity}: 
    android.view.InflateException: Binary XML file line #13: 
    Error inflating class TextView

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
...

Caused by: android.view.InflateException: 
    Binary XML file line #13: Error inflating class TextView
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129)
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14)
at android.app.Activity.performCreate(Activity.java:5008)
...

Caused by: android.content.res.Resources$NotFoundException: 
    File res/drawable/ic_accessible_white_36px.xml from drawable resource ID #0x7f02004b
at android.content.res.Resources.loadDrawable(Resources.java:1918)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
at android.widget.TextView.<init>(TextView.java:622)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:60)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:56)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103)
at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:963)
at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:1022)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129) 
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14) 
at android.app.Activity.performCreate(Activity.java:5008) 
...

Caused by: org.xmlpull.v1.XmlPullParserException:
    Binary XML file line #1: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:877)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:818)
at android.content.res.Resources.loadDrawable(Resources.java:1915)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
at android.widget.TextView.<init>(TextView.java:622) 
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:60) 
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:56) 
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:103) 
at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:963) 
at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:1022) 
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129) 
at au.com.angryitguy.testsvg.MainActivity.onCreate(MainActivity.java:14) 
at android.app.Activity.performCreate(Activity.java:5008) 
...

नहीं, आप नहीं कर सकते, क्योंकि एसवीजी फाइलें मूल रूप से समर्थित नहीं हैं । आपको एक वेक्टरड्राइव का उपयोग करना होगा, इसके बजाय (जो केवल एसवीजी चश्मा के एक सबसेट का उपयोग करता है)।
फैंटमैक्सएक्स

2
यह देखने के लिए कि कैसे drawableLeft, drawableRight, drawableTop, drawableBottom के साथ
VectorDrawable का उपयोग

मुझे यह काम मेरे लिए मिला: android.jlelse.eu/…
Huy Tower

जवाबों:


186

SVG आस्तियों के लिए drawableRight आदि का उपयोग करना संभव है?

हाँ

AppCompatTextView अब समर्थन करता है app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompatऔर app:drawableEndCompatयौगिक ड्रॉएबल, drawable प्रकार जैसे बैकपोर्टेड समर्थन VectorDrawableCompat

इसे अपनी ग्रेडेल फ़ाइल में शामिल करें

implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'

अपने पाठ दृश्य में आप उपयोग कर सकते हैं

app:drawableLeftCompat
app:drawableStartCompat

यदि आपको एप्लिकेशन का उपयोग करते समय समस्याएँ हैं: drawableLeftCompat, app: drawableStartCompat बटन में आपको अपनी लाइब्रेरी को अपडेट करना होगा

androidx.appcompat: appcompat: 1.2.0-alpha01

उनके पास एक बग था

androidx.appcompat: appcompat: 1.1.0-alpha01

आप डॉक्स देख सकते हैं


या यदि आप अभी तक अपडेट नहीं करना चाहते हैं, तो:

क्योंकि ऐसा लगता है कि Google इस मुद्दे पर जल्द ही कुछ भी नहीं करने जा रहा है, मुझे अपने सभी ऐप्स के लिए एक और ठोस पुन: प्रयोज्य समाधान के साथ आना पड़ा:

  1. सबसे पहले ऐड कस्टम TextView अपने अनुप्रयोग के attrs.xml फ़ाइल में जिम्मेदार बताते हैं "res / values / attrs.xml" :

    <resources>
        <declare-styleable name="CustomTextView">
            <attr name="drawableStartCompat" format="reference"/>
            <attr name="drawableEndCompat" format="reference"/>
            <attr name="drawableTopCompat" format="reference"/>
            <attr name="drawableBottomCompat" format="reference"/>
        </declare-styleable>
    </resources>
  2. फिर इस तरह से कस्टम टेक्स्ट व्यू क्लास बनाएं:

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.drawable.Drawable;
    import android.os.Build;
    import android.support.v7.content.res.AppCompatResources;
    import android.support.v7.widget.AppCompatTextView;
    import android.util.AttributeSet;
    
    public class CustomTextView extends AppCompatTextView {
        public CustomTextView(Context context) {
            super(context);
        }    
        public CustomTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initAttrs(context, attrs);
        }
        public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initAttrs(context, attrs);
        }
    
        void initAttrs(Context context, AttributeSet attrs) {
            if (attrs != null) {
                TypedArray attributeArray = context.obtainStyledAttributes(
                        attrs,
                        R.styleable.CustomTextView);
    
                Drawable drawableStart = null;
                Drawable drawableEnd = null;
                Drawable drawableBottom = null;
                Drawable drawableTop = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    drawableStart = attributeArray.getDrawable(R.styleable.CustomTextView_drawableStartCompat);
                    drawableEnd = attributeArray.getDrawable(R.styleable.CustomTextView_drawableEndCompat);
                    drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat);
                    drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat);
                } else {
                    final int drawableStartId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableStartCompat, -1);
                    final int drawableEndId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableEndCompat, -1);
                    final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, -1);
                    final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, -1);
    
                    if (drawableStartId != -1)
                        drawableStart = AppCompatResources.getDrawable(context, drawableStartId);
                    if (drawableEndId != -1)
                        drawableEnd = AppCompatResources.getDrawable(context, drawableEndId);
                    if (drawableBottomId != -1)
                        drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId);
                    if (drawableTopId != -1)
                        drawableTop = AppCompatResources.getDrawable(context, drawableTopId);
                }
    
                // to support rtl
                setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, drawableTop, drawableEnd, drawableBottom);
                attributeArray.recycle();
            }
        }
    }
  3. अब आप इसे अपने कस्टम विशेषताओं द्वारा किसी भी लेआउट में आसानी से उपयोग कर सकते हैं:

    <YOUR_VIEW_PACKAGE.CustomTextView
        android:id="@+id/edt_my_edit_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:drawableStartCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableEndCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableTopCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        app:drawableBottomCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
        />
    • आप बटन , EditText और RadioButton के साथ भी ऐसा ही कर सकते हैं क्योंकि वे TextView से प्राप्त हुए हैं

उम्मीद है की यह मदद करेगा :)


4
बहुत उपयोगी जवाब। वैसे भी, मैं दादू के बहुत ही पूर्ण उत्तर को भी पढ़ने की सलाह देता हूं । vectorDrawables { useSupportLibrary = true }मेरे build.gradleजवाब से हटने से पता चलता है कि मेरे लिए काम किया गया था।
सैम

मैंने ऐसा किया है और मुझे अब निम्न समस्या है: जब मैं XML में
ओक्लिक्क

3
मैं vectorDrawables useSupportLibrary = trueग्रेडेल से लाइन हटाने से असहमत हूं । जब आप इसे हटाते हैं, तो आप अभी भी अपने विचारों के अंदर वैक्टर डाल सकते हैं, लेकिन वे उसी तरह से आकार देते हैं जैसे pngs, जिसका अर्थ है कि वे खिंच जाएंगे और दानेदार हो जाएंगे। यदि आप 5.0 / API21 से नीचे के उपकरण चाहते हैं, तो वे वास्तव में वैक्टर को सही ढंग से आकार देते हैं, ताकि वे क्रिस्प दिखें, आपको ग्रेडिंग फाइल के अंदर उस लाइन का उपयोग करना होगा। आईडीई को इनवॉइस में डालकर उन क्षेत्रों को खोजने के लिए जहां आप गलत तरीके से वैक्टर का उपयोग कर रहे हैं और फिर आपको app:srcCompatएक्सएमएल के माध्यम से उपयोग करना होगा या कोड के माध्यम से सेट करना होगाVectorDrawableCompat.create()
जघन्य खेल

app:drawableEndCompatबेहतर RTL समर्थन के लिए कैसे जोड़ें ? कारण setCompoundDrawablesRelativeWithIntrinsicBoundsएपीआई स्तर 17 कम से कम की जरूरत है।
डॉ। जैकी

1
प्रोग्रामेबल रूप से ड्रॉ करने के बारे में क्या?
एंड्रॉइड डेवलपर

77

यह समाधान अब सही नहीं है। 23.3.0 संस्करण वेक्टर ड्राअब से केवल ऐप के माध्यम से लोड किया जा सकता है: srcCompat या setImageResource ()

परत-सूची या चयनकर्ता में अपने वेक्टर को आकर्षित करने की कोशिश करें:

<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@drawable/ic_accessible_white_wrapped"
    android:background="@color/colorPrimary"
    android:textColor="#FFFFFF"
    android:textSize="22sp"
    android:text="Hello World!"/>

ic_accessible_white_wrapped.xml:

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

यह अच्छा काम करता है। धन्यवाद .. लेकिन ऐसा लगता है कि आप सीधे "android: drawableXXXXX" में एक एसवीजी को संदर्भित नहीं कर सकते हैं, आपको इसे किसी और चीज़ में लपेटना होगा।
गुस्से में गुप्ता

1
हाँ। आप इसे सीधे उपयोग नहीं कर सकते। केवल ऐप के रूप में: srcCompat या लिपटे या प्रोग्रामेटिक रूप से। यह यहाँ वर्णित किया गया था: android-developers.blogspot.ru/2016/02/…
एलेक्जेंडर शटको

आह .. धन्यवाद .. मैं उस पैराग्राफ को देख सकता हूँ जिसका आप जिक्र कर रहे हैं। तो, क्या यह अभी भी एक बग है अगर वे आपको यह नहीं करने के लिए कहते हैं? ;)
नाराजगी

1
मुझे लगता है कि यह सब पिछड़ी संगतता के बारे में है। ऐसा लग रहा है कि पूर्ण svg समर्थन प्राप्त करने के लिए कुछ समस्या है, इसलिए उन्होंने कुछ वर्कअराउंड बनाए ...
एलेक्जेंडर शटको

2
@HarishGyanani समर्थन संस्करण 23.3.0 से, यह कोई लंबा समर्थन नहीं है। आपको अपनी गतिविधि में और कमांड जोड़ना होगा: static {if (Build.VERSION.SDK_INT <Build.VERSION_CODES.LOLLIPOP) {AppCompatDelegate.setCompatVectorFromResource.com/nabled (true); }}
Cuong Nguyen

75

सबसे अच्छा तरीका मैंने पाया:

Drawable leftDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);

9
8/25/17 तक यह एकमात्र ऐसी चीज है जो मेरे लिए काम करती है (ड्रा करने योग्य प्रोग्राम की स्थापना)। मैं वास्तव में इस्तेमाल किया:Drawable drawable = VectorDrawableCompat.create(getResources(), status.getIconResId(), wrapper.getTheme()); statusButton.setCompoundDrawablesRelativeWithIntrinsicBounds(null, drawable, null, null);
saiyancoder

2
के लिए minSdk setCompoundDrawablesWithIntrinsicBoundsहै 17 । अन्यथा यह महान काम करता है।
विक्टर रेंडिना

1
इसका मिस्डस्क 1 नहीं 17 है, आप शायद इसी तरह के एप्स को देखते हैं। setCompoundDrawablesWithIntrinsicBounds => minSdk 1; setCompoundDrawablesRelativeWithIntrinsicBounds => minSdk 17
正宗 白 白


मैंने इसे बाइंडिंग एडेप्टर के साथ उपयोग किया और प्रभावी ढंग से काम करता है, धन्यवाद!
Ric17101

61

यहाँ कुछ उत्तरों को पूरक करने के लिए: आप drawableLeft(आदि) के रूप में काम करने के लिए वेक्टरड्राइव प्राप्त कर सकते हैं, लेकिन यह सपोर्ट लाइब्रेरी संस्करण पर निर्भर करता है और यह एक मूल्य के साथ आता है।

किन मामलों में यह काम करता है? मैंने मदद करने के लिए यह आरेख बनाया है (समर्थन लाइब्रेरी के लिए मान्य 23.4.0 से - कम से कम - 25.1.0)।

वेक्टरड्राएबल धोखा दे


2
यह बहुत अच्छा है लेकिन आपको स्टैटिक ब्लॉक में विधि का नाम सही करना चाहिएsetCompatVectorFromResourcesEnabled
विकास पाटीदार

1
setCompatVectorFromResourcesEnabled समाधान 25.3.1 पर काम नहीं करता है, दुर्भाग्य से
Ilja S.

From 23.3.0 version vector drawables can only be loaded via app:srcCompat or setImageResource()इसलिए यह समाधान हटा दिया गया है और काम नहीं करेगा
user25

सक्षम करने setCompatVectorFromSourcesEnabled(true)से android:backgroundएंड्रॉइड 4.x पर vectordrawables लोड करना संभव हो जाता है। तो धन्यवाद! (आपको वास्तविक वेक्टर को एकल आइटम परत-सूची में लपेटने की आवश्यकता है)
पीटरडक

14

अन्य जवाबों में से किसी ने भी काम नहीं किया, यहां बताया गया है कि मैंने किस तरह एक VectorDrawableको जोड़ा है TextView, आपको नीचे दिए गए VectorDrawableCompat.create()काम का उपयोग करना चाहिए :VectorDrawablesAndroid L

TextView titleTextView = (TextView) viewHolder.getView(android.R.id.text1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
       Drawable leftDrawable = AppCompatResources
                            .getDrawable(context, R.drawable.ic_tickbox);
       titleTextView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
}
else
{
      //Safely create our VectorDrawable on pre-L android versions. 
       Drawable leftDrawable = VectorDrawableCompat
                            .create(context.getResources(), R.drawable.ic_tickbox, null);
       titleTextView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
}

संक्षिप्त, प्यारा और सटीक!


यह एंड्रॉइड पी के लिए काम करता है, और न्यूनतम एपीआई स्तर 26 (लक्ष्य 28)
15

@MiStr - यह भी पीछे की ओर संगत है :)
सकीबॉय

9

Google से: एंड्रॉइड सपोर्ट लाइब्रेरी 23.3.0 के रूप में, वेक्टर वेक्टर का समर्थन केवल ऐप के माध्यम से किया जा सकता है: srcCompat या setImageResource () ।।

http://android-developers.blogspot.ru/2016/02/android-support-library-232.html


1
इसका मतलब है कि अब कोई समाधान नहीं है
किलर

अपने वेक्टर ड्रॉबल को लेयर-लिस्ट या चयनकर्ता में शामिल करने का प्रयास करें: <TextView Android: id = "@ id / textView" Android: Layout_width = "match_parent" android: layout_height = "wra_content" android: drawableRight = "@ drawable / ic_accessible_white_wrapped"। Android: background = "@ color / colorPrimary" android: textColor = "# FFFFFF" Android: textSize = "22sp" android: text = "हैलो वर्ल्ड!" /> ic_accessible_white_rapped.xml: <परत-सूची xmlns: Android = " schemas " .android.com / apk / res / android "> <आइटम android: drawable =" @ drawable / ic_accessible_white_36px "/> </ परत-सूची>
Null Pointer Exception

9

यह संभव है कि सीधे वेक्टर ड्रा को xml में सेट करें, लेकिन आपने डेटा बाइंडिंग फ्रेमवर्क को शामिल किया है।

बस लिखें

<TextView
...
android:drawableRight="@{@drawable/ic_accessible_white_36px}"/>

और अपने पूरे लेआउट को एक <layout>टैग में लपेटें , ताकि मूल रूप से आपका xml जैसा दिखे:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="au.com.angryitguy.testsvg.MainActivity">


        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:drawableRight="@{@drawable/ic_accessible_white_36px}"
            android:text="Hello World!"
            android:textColor="#FFFFFF"
            android:textSize="22sp"/>
    </RelativeLayout>
</layout>

डेटा बाइंडिंग ढांचे को सक्रिय करने के लिए बस जोड़ें

android {
    ....
    defaultConfig {
        dataBinding {
            enabled = true
        }
    }
}

आपको बाइंडिंग लाइब्रेरी की किसी भी अन्य सुविधाओं का उपयोग करने की आवश्यकता नहीं है

संपादित करें:

यदि आप वेक्टर ड्रॉ का उपयोग करना चाहते हैं, तो लॉलीपॉप से ​​पहले आपको वेक्टर वेक्टर का उपयोग करने में सक्षम होना चाहिए

vectorDrawables.useSupportLibrary = true

तो आपके build.gradleलिए 2 नए आदेश हैं:

android {
    ....
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
        dataBinding {
            enabled = true
        }
    }
}

टिप्पणी के लिए rkmax के लिए धन्यवाद


यह एक अच्छा विचार है, लेकिन आपको काम करने के लिए एक बाध्यकारी एडेप्टर लिखना होगा। यहाँ एक कार्यशील उदाहरण दिया गया है: gist.github.com/lisawray/78c33f76809d2bcbbec9983e2c141a70
BladeCoder

1
मुझे कहना होगा कि यह मेरे लिए काम करता है, लेकिन आपको vectorDrawables.useSupportLibraryऐप / बिल्ड.ग्रेड पर सक्षम करना होगा और गतिविधि पर
AppCompatDelegate.setCompatVectorFromResourceEnabled

मैं डिफ़ॉल्ट जोड़ने के लिए भूल गया है build.gradleकि इस कारण से यह काम नहीं कर रहा है हो सकता है
हंस एम

धन्यवाद - आप एक जीवन रक्षक हैं!
वैन

यह एक रेखांकित जवाब है!
DYS

6

मैं सभी उत्तरों के माध्यम से गया और नवीनतम एंड्रॉइड स्टूडियो 3.0.1 और AppCompat सपोर्ट लाइब्रेरी 26.1.0 का उपयोग करके मैं यह आश्वासन दे सकता हूं कि यह ठीक काम करता है।

में build.gradle (ऐप्लिकेशन) फ़ाइल

android {
    compileSdkVersion 26
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'
}

और फैली हुई गतिविधि AppcompatActivityमें यह बाहर के तरीके यानी एक staticब्लॉक शामिल हैं

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}  

या यदि आप चाहते हैं कि इसे पूरे ऐप पर लागू किया जाए, तो इस लाइन को क्लास में फैली Applicationक्लास के अंदर शामिल करें

override fun onCreate() {
    super.onCreate()
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}

एक्सएमएल में टेक्स्टव्यू

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

<TextView
        android:id="@+id/passName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/account_drawableleft_selector"
        android:drawablePadding="5dp"
        android:ellipsize="marquee"
        android:fontFamily="@font/montserrat_light_family"
        android:gravity="center_vertical"
        android:marqueeRepeatLimit="marquee_forever"
        android:paddingRight="10dp"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:textColor="@color/app_text_color"
        android:textSize="12sp"
        tools:text="Account Name" />
</LinearLayout>

account_drawableleft_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_account_circle_24dp" /> <!-- checked -->
</selector>

क्या एपीआई पर ठीक काम करता है? आपने 19 या 20 को कोशिश की?
गोताखोर

क्या आप दिखा सकते हैं कि आप XML में कैसे उपयोग drawableRightकरते हैं TextView?
गोताखोर

2
उपर्युक्त कुछ की तरह, अगर यू वेक्टर वेक्टर को सीधे उपयोग कर सकते हैं, जैसा कि ड्रॉबलटेफ्ट यू को अभी भी यह दुर्घटना या अपवाद मिलता है, इस प्रकार वर्कअराउंड उस वेक्टर xml का उपयोग टेक्स्टव्यू के लिए ड्राएबलटेफ्ट के चयनकर्ता के रूप में करना है। उपयोग यू संपादित उत्तर में देख सकते हैं।
अमित तुमकुर

1
यह काम पर नहीं जा रहा है, आप सीधे एक्सएमएल में
TextView के

API 19 और 20 में इसका परीक्षण करें। मैंने इसके बजाय एप्लिकेशन क्लास में AppCompatDelegate.setCompatVectorFromResourcesEnabled का उपयोग किया। एक आकर्षण की तरह काम करना!
Red M


5

मुझे इस प्रश्न का उत्तर देने में इतनी देर हो गई क्योंकि मैं इस समस्या से देर से जुड़ा। मेरे पास टेक्स्ट व्यू के साथ svg / वेक्टर ड्रॉबल्स के साथ एक ही मुद्दा था। अपनी खुद की कस्टम ड्रॉएबल बनाने के बजाय मैं नीचे दिए गए कोड की 2 लाइनों के साथ अपनी समस्या को ठीक करने में सक्षम हूं:

Drawable drawableTop = AppCompatResources.getDrawable(view.getContext(), iconId);
view.setCompoundDrawablesWithIntrinsicBounds(null, drawableTop, null, null);

आशा है कि यह आपकी मदद करेगा।


पूर्व Lउपकरणों के साथ संगत नहीं है।
सकीबॉय

@ साकिबॉय हाँ यह है, जैसा कि मैं न्यूनतम एपीआई 17 के साथ इस कोड का उपयोग कर रहा हूं।
राहुल शर्मा

VectorDrawablesप्री-एल चलाने वाले सभी उपकरणों पर काम नहीं करता है , बस Sayin। इस उत्तर का उपयोग करते समय सतर्क रहें, क्योंकि उपयोग करने के लिए अधिक सटीक एपीआई सुरक्षित हैं।
साकिबॉय

4

मैंने इसके लिए एक छोटी सी लाइब्रेरी तैयार की है - टेक्स्टव्यू-रिच-ड्राएबल (यह कंपाउंड-ड्रॉबल्स के आकार और टिनिंग को परिभाषित करने का भी समर्थन करता है)।

<com.tolstykh.textviewrichdrawable.TextViewRichDrawable
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Some text"
    app:compoundDrawableHeight="24dp"
    app:compoundDrawableWidth="24dp"
    app:drawableTopVector="@drawable/some_vector_drawble"
    app:drawableEndVector="@drawable/another_vector_drawable"
    app:drawableTint="@color/colorAccent" />

और निर्भरता

compile 'com.tolstykh.textviewrichdrawable:textview-rich-drawable:0.3.2'

यहाँ छवि विवरण दर्ज करें


3

यदि आप बाइंडिंग का उपयोग कर रहे हैं, तो TextView में वैक्टर का उपयोग करने के लिए समान दृष्टिकोण रखने का एक और जादू का तरीका है। उन्हें लपेटकर:

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

यह जादुई रूप से काम करेगा, मैंने जांच नहीं की है कि पर्दे के पीछे क्या हो रहा है, लेकिन मुझे लगता है कि TextView या इसी तरह की getDrawableविधि का उपयोग कर रहा है AppCompatResources


2

बहज़ाद बहमनार के जवाब के आधार पर , मैंने देखा कि मैं सामान्य png फ़ाइलों के लिए android की सामान्य विशेषताओं का उपयोग नहीं कर सका:

android:drawableTop
android:drawableBottom
etc

क्योंकि यह शून्य में बदल दिया जाएगा

Drawable drawableTop = null;
...
setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, drawableTop, drawableEnd, drawableBottom);

अगर app:drawableTopCompatसेट नहीं किया गया था, लेकिन android:drawableTop(उदाहरण के लिए) था।

यहाँ पूर्ण समाधान है:

public class CustomTextView extends AppCompatTextView {
    private static final int NOT_SET = -1;
    private static final int LEFT = 0;
    private static final int START = 0;
    private static final int TOP = 1;
    private static final int RIGHT = 2;
    private static final int END = 2;
    private static final int BOTTOM = 3;

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }

    void initAttrs(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        Drawable[] drawablesArr = getCompoundDrawables();

        TypedArray attributeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
        Drawable drawableStart = null;
        Drawable drawableEnd = null;
        Drawable drawableBottom = null;
        Drawable drawableTop = null;
        Drawable drawableLeft = null;
        Drawable drawableRight = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            drawableStart = attributeArray.getDrawable(R.styleable.CustomTextView_drawableStartCompat);
            drawableEnd = attributeArray.getDrawable(R.styleable.CustomTextView_drawableEndCompat);
            drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat);
            drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat);
            drawableLeft = attributeArray.getDrawable(R.styleable.CustomTextView_drawableLeftCompat);
            drawableRight = attributeArray.getDrawable(R.styleable.CustomTextView_drawableRightCompat);
        } else {
            final int drawableStartId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableStartCompat, NOT_SET);
            final int drawableEndId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableEndCompat, NOT_SET);
            final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, NOT_SET);
            final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, NOT_SET);
            final int drawableLeftId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableLeftCompat, NOT_SET);
            final int drawableRightId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableRightCompat, NOT_SET);

            if (drawableStartId != NOT_SET)
                drawableStart = AppCompatResources.getDrawable(context, drawableStartId);
            if (drawableLeftId != NOT_SET)
                drawableLeft = AppCompatResources.getDrawable(context, drawableLeftId);
            if (drawableEndId != NOT_SET)
                drawableEnd = AppCompatResources.getDrawable(context, drawableEndId);
            if (drawableRightId != NOT_SET)
                drawableRight = AppCompatResources.getDrawable(context, drawableRightId);
            if (drawableBottomId != NOT_SET)
                drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId);
            if (drawableTopId != NOT_SET)
                drawableTop = AppCompatResources.getDrawable(context, drawableTopId);
        }

        drawableStart = (drawableStart != null ? drawableStart : drawablesArr[START]);
        drawableLeft = (drawableLeft != null ? drawableLeft : drawablesArr[LEFT]);
        drawableStart = (drawableStart != null ? drawableStart : drawableLeft);

        drawableEnd = (drawableEnd != null ? drawableEnd : drawablesArr[END]);
        drawableRight = (drawableRight != null ? drawableRight : drawablesArr[RIGHT]);
        drawableEnd = (drawableEnd != null ? drawableEnd : drawableRight);

        drawableBottom = (drawableBottom != null ? drawableBottom : drawablesArr[BOTTOM]);
        drawableTop = (drawableTop != null ? drawableTop : drawablesArr[TOP]);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, drawableTop, drawableEnd, drawableBottom);
        } else {
            setCompoundDrawables(drawableStart, drawableTop, drawableEnd, drawableBottom);
        }

        attributeArray.recycle();
    }
}

इसका उत्तर स्वीकार किया जाना चाहिए। सामान्य पीएनजी फाइलों और विशेषताओं के साथ कार्य करें drawableTop, drawableBottom। स्वीकृत जवाब png फ़ाइल और drawableTop, drawableBottom विशेषताओं के साथ काम नहीं करता है।
भार्गव पंड्या

2

Build.gradle (ऐप) फ़ाइल में

android {
    compileSdkVersion 26
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }

    dataBinding {
        enabled = true
    }
}

...

public class BindingUtils {
    @BindingAdapter("android:drawableRight")
    public static void setDrawableStart(TextView textView, int resourceId) {
        Drawable drawable = AppCompatResources.getDrawable(textView.getContext(), resourceId);
        Drawable[] drawables = textView.getCompoundDrawables();
        textView.setCompoundDrawablesWithIntrinsicBounds(drawable,
                drawables[1], drawables[2], drawables[3]);
    } 
}

उपयोग (जब डेटाबाइंडिंग)

android:drawableRight="@{viewModel.ResId}"

या (सामान्य)

android:drawableRight="@{@drawable/ic_login_24dp}"

1

वेक्टर चित्र का उपयोग करना

kotlin

 val drawable1 = VectorDrawableCompat.create(resources, R.drawable.ic_rb_username, theme)
        yourView.setCompoundDrawablesRelativeWithIntrinsicBounds( drawable1, null, null, null)

जावा

  Drawable drawable1 = VectorDrawableCompat.create(getResources(), R.drawable.ic_rb_username, getTheme());
        yourView.setCompoundDrawablesRelativeWithIntrinsicBounds( drawable1, null, null, null);

1

पिछड़े संगतता उपयोग के लिए:

TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, left, top, right, bottom)

0

Im इस समस्या को हल करने के लिए बाइंडिंग एडाप्टर का उपयोग कर रहा है

@JvmStatic
@BindingAdapter("drawableSvgLeft")
fun addDrawableSvgLeft(textView: TextView,drawable: Drawable){
    textView.setCompoundDrawablesWithIntrinsicBounds(drawable,null,null,null)
}

@JvmStatic
@BindingAdapter("drawableSvgRight")
fun addDrawableSvgRight(textView: TextView,drawable: Drawable){
    textView.setCompoundDrawablesWithIntrinsicBounds(null,null,drawable,null)
}

और मेरे लेआउट में इस तरह से उपयोग करना

<TextView
  drawableSvgRight="@{@drawable/svg_ic_battle_trophy}"
  .....

शायद VectorDrawables.useSupportLibrary = सही डिफ़ॉल्ट डिफ़ॉल्ट में आवश्यक है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.