TextViewまたはImageViewでVectorDrawableアセットを使用すると、「Android:DrawableRight」/「Android:DrawableEnd」/「Android:DrawableStart」/「Android:DrawableLeft」を使用するとランタイムクラッシュが発生します。
アプリは警告なしで正常にコンパイルされます。
使ってます
私が見つけたのは、このようにクラッシュすることなく、プログラムでJavaのSVGを割り当てることができるということです。
TextView tv = (TextView) findViewById(R.id.textView);
tv.setCompoundDrawablesWithIntrinsicBounds(null,null, getResources().getDrawable(R.drawable.ic_accessible_white_36px),null);
(これは23.2のサポートライブラリのバグであると思われます。)
しかし、SVGアセットにdrawableRightなどを使用することは可能ですか?
これが私のレイアウトです
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="au.com.angryitguy.testsvg.MainActivity">
<TextView
Android:id="@+id/textView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:drawableRight="@drawable/ic_accessible_white_36px"
Android:background="@color/colorPrimary"
Android:textColor="#FFFFFF"
Android:textSize="22sp"
Android:text="Hello World!"/>
</RelativeLayout>
これが私の活動です
package au.com.angryitguy.testsvg;
import Android.content.Intent;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
以下は、Googleのマテリアルデザインサイトの変更されていないVectorDrawableアセットです。
<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'
}
これがクラッシュです。 (textviewを参照するinflateエラーに注意してください。)
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)
sVGアセットにdrawableRightなどを使用できますか?
はい
AppCompatTextViewnow は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
古い回答
グーグルはすぐにこの問題について何もしないと思われるので、すべてのアプリに対してより強固で再利用可能なソリューションを考え出す必要がありました。
まず、アプリのattrs.xmlファイルにカスタムTextView属性を追加します "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>
次に、次のようなカスタム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();
}
}
}
カスタム属性を使用して、任意のレイアウトで簡単に使用できるようになりました。
<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 -->
/>
お役に立てれば :)
このソリューションはもはや正しくありません。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>
私が見つけた最良の方法:
Drawable leftDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
ここでいくつかの答えを補足するために:VectorDrawableをdrawableLeft
(など)として機能させることができますが、サポートライブラリのバージョンに依存し、価格が付属しています
どの場合に機能しますか? この図 を作成しました(サポートライブラリ23.4.0から-少なくとも-25.1.0で有効)。
他の答えはどれもうまくいきませんでした、ここでVectorDrawable
をTextView
に追加しました。Android L
の下のVectorDrawables
を扱うときはVectorDrawableCompat.create()
を使用する必要があります。
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);
}
短く、甘い、そしてポイントまで!
Xmlでベクタードローアブルを直接設定することは可能ですが、データバインディングフレームワークが含まれています。
書くだけ
<TextView
...
Android:drawableRight="@{@drawable/ic_accessible_white_36px}"/>
レイアウト全体を<layout>
タグでラップするため、基本的にxmlは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<layout>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="au.com.angryitguy.testsvg.MainActivity">
<TextView
Android:id="@+id/textView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@color/colorPrimary"
Android:drawableRight="@{@drawable/ic_accessible_white_36px}"
Android:text="Hello World!"
Android:textColor="#FFFFFF"
Android:textSize="22sp"/>
</RelativeLayout>
</layout>
データバインディングフレームワークをアクティブにするには、追加するだけです
Android {
....
defaultConfig {
dataBinding {
enabled = true
}
}
}
バインディングライブラリの他の機能を使用する必要はありません。
編集:
もちろん、ロリポップの前にベクトルドロアブルを使用する場合は、次を使用してサポートベクトルドロアブルを有効にする必要があります。
vectorDrawables.useSupportLibrary = true
したがって、build.gradle
には2つの新しいコマンドが必要です。
Android {
....
defaultConfig {
vectorDrawables.useSupportLibrary = true
dataBinding {
enabled = true
}
}
}
発言について rkmax に感謝
Googleから:Android Support Library 23.3.0の時点で、サポートベクタードロウアブルはapp:srcCompatまたはsetImageResource()経由でのみロードできます。
http://Android-developers.blogspot.ru/2016/02/Android-support-library-232.html
この問題に遅刻したため、この質問に答えるのが遅すぎました。 TextViewを使用したsvg/vectorドロアブルでも同じ問題が発生しました。独自のカスタムドローアブルを作成する代わりに、次の2行のコードで問題を解決できます。
Drawable drawableTop = AppCompatResources.getDrawable(view.getContext(), iconId);
view.setCompoundDrawablesWithIntrinsicBounds(null, drawableTop, null, null);
それがあなたを助けることを願っています。
すべての回答を確認し、最新の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'
}
そして、アクティビティを拡張するAppcompatActivityには、この外部メソッド、つまり静的ブロックが含まれます
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
または、これをアプリ全体に適用する場合は、この行をApplicationクラスを拡張するクラス内に含めるだけです
override fun onCreate() {
super.onCreate()
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}
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>
appcompat:1.1. 使用可能
app:drawableLeftCompat
app:drawableStartCompat
...
このための小さなライブラリを設計しました- 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'
バインディングを使用している場合、TextViewでベクターを使用するのと同じ方法を使用する別の魔法の方法があります。それらを次のようにラッピングします。
Android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
Android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
それは魔法のように機能します。私は舞台裏で何が起こっているのか調査していませんが、TextViewはgetDrawable
または同様のAppCompatResources
メソッドを使用していると思います。
Behzad Bahmanyarの answer に基づいて、通常のpngファイルに対してAndroidの通常の属性を使用できないことに気付きました。
Android:drawableTop
Android:drawableBottom
etc
でnullに置き換えられるため
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();
}
}
Vector Drawablesの使用
コトリン
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);
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]);
}
}
use(データバインディング時)
Android:drawableRight="@{viewModel.ResId}"
または(通常)
Android:drawableRight="@{@drawable/ic_login_24dp}"
下位互換性の使用:
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, left, top, right, bottom)