it-swarm.com.ru

Можно ли использовать VectorDrawable в кнопках и TextViews с помощью Android: DrawableRight?

Когда я использую ресурсы VectorDrawable в текстовом представлении или изображении, у меня возникает сбой во время выполнения при использовании "Android: DrawableRight"/"Android: DrawableEnd"/"Android: DrawableStart"/"Android: DrawableLeft".

Приложение будет прекрасно компилироваться без каких-либо предупреждений.

Я использую

  • Gradle 1.5
  • Библиотека поддержки 23.2 ('com.Android.support:appcompat-v7:23.2.0')

Однако я обнаружил, что могу программно назначать SVG в Java без сбоев, подобных этому.

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

(Я подозреваю, что это ошибка библиотеки поддержки для 23.2.)

Но возможно ли использовать drawableRight и т.д. Для SVG-активов?

Вот мой макет

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

        }
    }

Вот немодифицированный актив VectorDrawable с сайта дизайна материалов 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>

Вот мое приложение 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'
}

Вот авария. (Обратите внимание на раздутые ошибки, которые ссылаются на текстовое представление.)

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) 
109
angryITguy

можно ли использовать drawableRight и т. д. для SVG-активов?

Да

AppCompatTextView сейчас поддерживает app:drawableLeftCompat, app:drawableTopCompat, app:drawableRightCompat, app:drawableBottomCompat, app:drawableStartCompat и app:drawableEndCompat составные объекты рисования, такие как VectorDrawableCompat.

Включите это в свой файл Gradle

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

В вашем текстовом представлении вы можете использовать

app:drawableLeftCompat
app:drawableStartCompat

Старый ответ

Поскольку, похоже, 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. Затем создайте пользовательский класс TextView следующим образом:

    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

Надеюсь это поможет :)

154
Behzad Bahmanyar

Это решение больше не является правильным. Начиная с версии 23.3.0, векторные изображения можно загружать только через app: 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>
75
Alexandr Shutko

Лучший способ, который я нашел:

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

Чтобы дополнить некоторые ответы здесь: вы можете заставить VectorDrawable работать как drawableLeft (и т.д.), Но это зависит от версии библиотеки поддержки и поставляется с ценой.

В каких случаях это работает? Я сделал эта схема , чтобы помочь (действительно для библиотеки поддержки 23.4.0 до - по крайней мере - 25.1.0).

VectorDrawable cheatsheet

59
David Ferrand

Ни один из других ответов не сработал, вот как я добавил VectorDrawable к TextView, вы должны использовать VectorDrawableCompat.create() при работе с VectorDrawables ниже 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);
}

Коротко, сладко и точно!

14
Sakiboy

Можно напрямую установить векторные элементы рисования в 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
        }
    }
}

Вам не нужно использовать какие-либо другие функции библиотеки привязки

EDIT:

Конечно, если вы хотите использовать векторную графику перед запуском леденцов, вам нужно включить опорные векторные рисунки, используя

vectorDrawables.useSupportLibrary = true

Итак, вашему build.gradle нужны 2 новые команды:

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

спасибо rkmax за замечание

9
Hans M

От Google: Начиная с Android Библиотека поддержки 23.3.0, векторные вспомогательные векторные объекты можно загружать только через app: srcCompat или setImageResource () ..

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

9
paulzeng

Я так поздно отвечаю на этот вопрос, так как запоздал с этой проблемой. У меня была та же проблема с svg/vector drawables с TextView. Вместо того, чтобы создавать свой собственный пользовательский объект для рисования, я могу решить мою проблему с помощью двух строк кода, как показано ниже:

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

Надеюсь, это поможет вам.

5
Rahul Sharma

Я просмотрел все ответы и, используя новейшую Android studio 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'
}

А в Activity, расширяющий AppcompatActivity, включите этот внешний метод, то есть статический блок.

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}  

или если вы хотите, чтобы это было применено ко всему приложению, просто включите эту строку в класс, расширяющий класс приложения.

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

Textview в 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

с appcompat: 1.1. вы можете использовать

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

Для этого я разработал крошечную библиотеку - textview-rich-drawable (она также поддерживает определение размера и оттенков составных объектов).

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

enter image description here

3
Oleksandr

Если вы используете связывание, существует другой магический способ использовать тот же подход для использования векторов в TextView. Заворачивать их как:

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

Это будет работать волшебным образом, я не исследовал, что происходит за кулисами, но я предполагаю, что TextView использует метод getDrawable из AppCompatResources или аналогичный.

3
cesards

Основываясь на ответ Бехзада Бахманьяра, я заметил, что не могу использовать обычные атрибуты Android для обычных файлов png:

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

Использование векторного рисования

котлин

 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

В файле 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
Ahmad Aghazadeh