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
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)
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:
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>
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();
}
}
}
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 -->
/>
J'espère que cela t'aides :)
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>
Le meilleur moyen que j'ai trouvé:
Drawable leftDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
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).
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!
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
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
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.
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>
à partir de appcompat: 1.1. vous pouvez utiliser
app:drawableLeftCompat
app:drawableStartCompat
...
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'
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.
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();
}
}
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);
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}"
Pour la compatibilité ascendante, utilisez:
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, left, top, right, bottom)