web-dev-qa-db-fra.com

Est-il possible d'utiliser VectorDrawable dans les boutons et les TextViews avec Android: DrawableRight?

Lorsque j'utilise des ressources VectorDrawable dans une vue de texte ou une image, un blocage de l'exécution apparaît lorsque j'utilise "Android: DrawableRight"/"Android: DrawableEnd"/"Android: DrawableStart"/"Android: DrawableLeft".

L'application compilera bien sans aucun avertissement.

J'utilise

  • Gradé 1.5
  • Bibliothèque de support 23.2 ('com.Android.support:appcompat-v7:23.2.0')

Ce que j’ai trouvé, c’est que je peux affecter par programme des SVG dans Java sans que cela ne se produise.

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

(Je soupçonne qu'il s'agit d'un bogue de la bibliothèque de support pour 23.2.)

Mais est-il possible d'utiliser drawableRight, etc. pour les actifs SVG?

Voici ma mise en page

<?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>

Voici mon activité

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);

        }
    }

Voici l'actif VectorDrawable non modifié du site de conception de matériaux de 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>

Voici mon application 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'
}

Voici le crash. (Notez les erreurs de gonflement qui font référence à textview.)

03-02 07:56:08.808 13863-13863/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   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)
                at Java.lang.reflect.Method.invokeNative(Native Method)
                at Java.lang.reflect.Method.invoke(Method.Java:511)
                at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:786)
                at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553)
                at dalvik.system.NativeStart.main(Native Method)
                                                    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)
                at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1079)
                at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2023)
                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) 
                at Java.lang.reflect.Method.invokeNative(Native Method) 
                at Java.lang.reflect.Method.invoke(Method.Java:511) 
                at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:786) 
                at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553) 
                at dalvik.system.NativeStart.main(Native Method) 
                                                    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) 
                at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1079) 
                at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2023) 
                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) 
                at Java.lang.reflect.Method.invokeNative(Native Method) 
                at Java.lang.reflect.Method.invoke(Method.Java:511) 
                at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:786) 
                at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553) 
                at dalvik.system.NativeStart.main(Native Method) 
                                                    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) 
                at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1079) 
                at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2023) 
                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) 
                at Java.lang.reflect.Method.invokeNative(Native Method) 
                at Java.lang.reflect.Method.invoke(Method.Java:511) 
                at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:786) 
                at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553) 
                at dalvik.system.NativeStart.main(Native Method) 
112
angryITguy

est-il possible d'utiliser drawableRight, etc. pour les actifs SVG?

Oui

AppCompatTextView maintenant prend en charge app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompat et app:drawableEndCompat drawables composés, prenant en charge les types extractibles rétroportés tels que VectorDrawableCompat.

Incluez ceci dans votre fichier de classement

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

Dans votre vue texte, vous pouvez utiliser

app:drawableLeftCompat
app:drawableStartCompat

Ancienne réponse

Comme il semble que Google ne fera rien dans un avenir proche, je devais proposer une solution réutilisable plus solide pour toutes mes applications:

  1. Commencez par ajouter les attributs personnalisés TextView dans le fichier attrs.xml de votre application "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. Créez ensuite une classe TextView personnalisée comme ceci:

    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. Vous pouvez maintenant l’utiliser facilement dans n’importe quelle mise en page grâce à vos attributs personnalisés:

    <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 -->
        />
    
    • Vous pouvez faire la même chose avec Button , EditText et RadioButton car ils sont dérivés de TextView

J'espère que cela t'aides :)

162
Behzad Bahmanyar

Cette solution n'est plus correcte. À partir de la version 23.3.0, vous ne pouvez charger des vecteurs que par l'intermédiaire de app: srcCompat ou setImageResource ()

Essayez d’emballer votre vecteur dans une liste de calques ou un sélecteur:

<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>
75
Alexandr Shutko

Le meilleur moyen que j'ai trouvé:

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

Pour compléter certaines des réponses ici: , vous pouvez faire en sorte que VectorDrawable fonctionne en tant que drawableLeft (etc.), mais cela dépend de la version de la bibliothèque de support et le prix est élevé.

Dans quels cas ça marche? J'ai fait ce diagramme pour aider (valable pour Support Library 23.4.0 à - au moins - 25.1.0).

VectorDrawable cheatsheet

59
David Ferrand

Aucune des autres réponses n'a fonctionné, voici comment j'ai ajouté un VectorDrawable à un TextView, vous devez utiliser VectorDrawableCompat.create() pour traiter VectorDrawables sous Android 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);
}

Bref, doux, et au point!

14
Sakiboy

Il est possible de définir directement des vecteurs dessinables au format xml, mais vous devez inclure le cadre de liaison de données.

Ecrivez

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

et envelopper toute votre mise en page dans une balise <layout>, afin que votre code XML ressemble à ceci:

<?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>

Pour activer le cadre de liaison de données, ajoutez simplement

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

Vous n'avez pas besoin d'utiliser d'autres fonctionnalités de la bibliothèque de liaisons

EDIT:

Bien sûr, si vous voulez utiliser des dessins vectoriels pré-Lollipop, vous devez activer le support des dessins vectoriels en utilisant

vectorDrawables.useSupportLibrary = true

Donc, votre build.gradle a besoin de 2 nouvelles commandes:

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

merci à rkmax pour la remarque

9
Hans M

Depuis Google: à partir de Android Bibliothèque de support 23.3.0, les fichiers vectoriels de support ne peuvent être chargés que via l'application: srcCompat ou setImageResource () ..

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

9
paulzeng

Je suis si tard pour répondre à cette question que j'ai collé tard avec ce problème. J'ai eu le même problème avec svg/vector drawables avec TextView. Au lieu de créer votre propre dessin personnalisable, je peux résoudre mon problème avec 2 lignes de code comme ci-dessous:

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

J'espère que cela vous aidera.

5
Rahul Sharma

Je suis allé dans toutes les réponses et en utilisant la dernière Android studio 3.0.1 et la bibliothèque de support appcompat 26.1.0, je peux vous assurer que cela fonctionne correctement.

Dans le fichier build.gradle (app)

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

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

Et dans Activity extended AppcompatActivity, incluez ces méthodes externes, c’est-à-dire un bloc statique.

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}  

ou si vous souhaitez que cela soit appliqué à l'ensemble de l'application, incluez simplement cette ligne dans Class Extension de la classe d'application

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

Textview en XML

<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>
5
Amit Tumkur

à partir de appcompat: 1.1. vous pouvez utiliser

app:drawableLeftCompat
app:drawableStartCompat
...
5
chezi shem tov

J'ai conçu une minuscule bibliothèque pour cela - textview-rich-drawable (il prend également en charge la définition de la taille et de la teinte des dessins composables).

<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" />

Et la dépendance

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

enter image description here

3
Oleksandr

Si vous utilisez la liaison, il existe un autre moyen magique d'avoir la même approche pour utiliser des vecteurs dans un TextView. Les envelopper comme:

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

Comme par magie, je n’ai pas enquêté sur ce qui se passe dans les coulisses, mais je suppose que TextView utilise la méthode getDrawable de la méthode AppCompatResources ou similaire.

3
cesards

Basé sur réponse de Behzad Bahmanyar, j'ai remarqué que je ne pouvais pas utiliser les attributs normaux d'Android pour les fichiers png normaux:

Android:drawableTop
Android:drawableBottom
etc

car il serait remplacé par null dans

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

si le app:drawableTopCompat n'était pas défini, mais que Android:drawableTop l'était (par exemple).

Voici la solution complète:

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();
    }
}
1
Goran Horia Mihail

Utilisation de Vector Drawables use

kotlin

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

Java

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

Dans le fichier build.gradle (app)

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]);
    } 
}

use (lors de la liaison de données)

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

Ou (normal)

Android:drawableRight="@{@drawable/ic_login_24dp}"
1
Ahmad Aghazadeh

Pour la compatibilité ascendante, utilisez:

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