web-dev-qa-db-ja.com

srcCompatでImageView以外にViewでベクターDrawableを使用する方法は?

app:srcCompatImageViewを使用すると、後方互換性のあるベクトルドロウアブルの使用が可能になります。しかし、どのようにしてView以外の他のImageViewsでそれらを使用できますか?たとえば、Android:drawableLeftのようなTextView属性。

また、MenuItemとともにAndroid:iconとしてベクトルDrawableを使用すると、次の例外でクラッシュが発生しました。

Fatal Exception: Android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
   at Android.view.LayoutInflater.createView(LayoutInflater.Java:626)
   at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:702)
   at Android.view.LayoutInflater.inflate(LayoutInflater.Java:470)
   at Android.view.LayoutInflater.inflate(LayoutInflater.Java:398)
   at Android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.Java:621)
   at Android.support.v7.view.menu.MenuItemImpl.setActionView(MenuItemImpl.Java:40)
   at Android.support.v4.view.MenuItemCompat.setActionView(MenuItemCompat.Java:310)
   at Android.support.v7.view.SupportMenuInflater$MenuState.setItem(SupportMenuInflater.Java:465)
   at Android.support.v7.view.SupportMenuInflater$MenuState.addItem(SupportMenuInflater.Java:479)
   at Android.support.v7.view.SupportMenuInflater.parseMenu(SupportMenuInflater.Java:196)
   at Android.support.v7.view.SupportMenuInflater.inflate(SupportMenuInflater.Java:118)
   at com.example.niceapp.context.main.MainActivity.onCreateOptionsMenu(MainActivity.Java:101)
   at Android.app.Activity.onCreatePanelMenu(Activity.Java:2578)

サポートライブラリ23.2.0では、この問題にどのように対処できますか?

39
razzledazzle

セレクターXML(razzledazzleの受け入れられた回答)を介した作業ソリューションがないAppCompatバージョン23.3.0の場合、プログラムでこれを行うことができます。

activity_main.xml

<Android.support.v7.widget.AppCompatImageButton
    Android:id="@+id/btnEnter"
    />

MainActivity.Java

AppCompatImageButton image = (AppCompatImageButton) findViewById(R.id.btnEnter);
if (image != null) {
    VectorDrawableCompat vcAccept = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept, getTheme());
    VectorDrawableCompat vcAcceptWhite = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept_white, getTheme());

    StateListDrawable stateList = new StateListDrawable();
    stateList.addState(new int[]{Android.R.attr.state_focused, -Android.R.attr.state_pressed}, vcAccept);
    stateList.addState(new int[]{Android.R.attr.state_focused, Android.R.attr.state_pressed}, vcAcceptWhite);
    stateList.addState(new int[]{-Android.R.attr.state_focused, Android.R.attr.state_pressed}, vcAcceptWhite);
    stateList.addState(new int[]{}, vcAccept);

    image.setImageDrawable(stateList);
}

このコードは、このセレクターxmlと同等です。

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_focused="true" Android:state_pressed="false" Android:drawable="@drawable/vc_accept" />
    <item Android:state_focused="true" Android:state_pressed="true" Android:drawable="@drawable/vc_accept_white" />
    <item Android:state_focused="false" Android:state_pressed="true" Android:drawable="@drawable/vc_accept_white" />
    <item Android:drawable="@drawable/vc_accept" />
</selector>

更新

API 23を使用してベクトルドロウアブルが表示されない場合、最初にVectorDrawableを通常のDrawableに変換する必要があります。 setCompoundDrawablesWithIntrinsicBoundsを使用する場合、これを行う必要がありますが、StateListDrawableの場合は必要ありません。

Drawable icon;
if (Android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
    icon = VectorDrawableCompat.create(getResources(), R.drawable.vc_icon, getContext().getTheme());
} else {
    icon = getResources().getDrawable(R.drawable.vc_icon, getContext().getTheme());
}
29
Petr Daňa

Update 2:サポートライブラリ23.4.0で再度有効にするオプションを追加しました:

AppCompatユーザーの場合、オプトインAPIを追加して、リソースからのベクターDrawables(23.2で見つかった動作)を AppCompatDelegate.setCompatVectorFromResourcesEnabled() で再度有効にします。メモリ使用量の問題と構成インスタンスの更新の問題を引き起こすため、デフォルトで無効になっている理由。

Update:これはバージョン23.3.0以降では機能しなくなりました

AppCompatユーザーの場合、バージョン23.2.0/23.2.1の実装で見つかった問題のために、Lollipop以前のデバイスのリソースからベクトルドロウアブルを使用できる機能を削除することにしました[ https:// code.google.com/p/Android/issues/detail?id=205236https://code.google.com/p/Android/issues/detail?id=204708] 。 app:srcCompatとsetImageResource()の使用は引き続き機能します。

Android Developers Google+投稿 から


AppCompatとapp:srcCompatを使用することは、ベクタードロアブルをアプリに統合する最も確実な方法です。

この引用は、サポートライブラリのバージョン23.2.0のリリースに関する公式の blogpost からのものです。

投稿には次のことも記載されています。

app:srcCompatの外部にあるベクトルDrawableを直接参照すると、Lollipopの前に失敗します。ただし、AppCompatは、StateListDrawableInsetDrawableLayerDrawableLevelListDrawableRotateDrawableなどの別のドロアブルコンテナで参照される場合、ベクトルドロアブルのロードをサポートします。このインダイレクションを使用すると、TextViewAndroid:drawableLeft属性などの場合にベクタードロアブルを使用できます。これは通常、ベクトルドロアブルをサポートできません。

これは、次の手順に変換されます。

ステップ1:

アプリに必要なベクターリソースを作成またはインポートします。たとえば、検索アイコン用のベクトルドロアブルを作成し、ic_action_search_vector.xmlという名前を付けることができます

ステップ2:

以前に作成したベクトルドロアブルの別のプロキシドロアブルリソースを作成します。前のic_action_search_vector.xmlの場合、ic_action_search.xmlは以下の行を含むことができる単純なStateListDrawableとして作成できます。

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

ビューで使用する別の描画可能リソースからベクトル描画可能を参照している場合、このステップはスキップできます。

ステップ3:

直接ベクトルドロアブルの代わりに、ベクトルドロアブル(ic_action_search.xml)を参照するドロアブルリソース(ここでは、ic_action_search_vector.xml)を使用します。メニューの場合、次のようになります。

<item Android:id="@+id/search"
        Android:title="@string/search"
        Android:icon="@drawable/ic_action_search"
        app:showAsAction="always"/>

これがその問題の解決策です!

45
razzledazzle

ベクトルドロアブルは、app:srcCompat以外の場所でLollipopの前に使用できますが、価格が付いています。

この図 を作成しました(サポートライブラリ23.4.0から-少なくとも-25.1.0に有効)。

VectorDrawable cheatsheet

16
David Ferrand

TextViewでVector Drawableをプログラムで追加できます。 drawableLeft/drawableRight/drawableTop/drawableBottom/drawableStart/drawableEndを追加するには、VectorDrawableCompatを使用します。

手順:

私。 TextViewがアクティビティ内にある場合:

TextView tvUserName= (TextView)findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);

ii。 TextViewがフラグメント内にある場合:

TextView tvUserName= (TextView )view.findViewById(R.id.et_username_or_email);
VectorDrawableCompat drawableCompat=VectorDrawableCompat.create(getActivity().getResources(), R.drawable.layer_list_ic_user, tvUserName.getContext().getTheme());
tvUserName.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableCompat, null, null, null);

VectorDrawableCompatの詳細については、こちらを参照してください link

6
Arshak

Android 5.0(APIレベル21)以降では、ベクトル描画可能サポートが提供されます。アプリの最小APIレベルが低い場合、Vector Asset Studioはベクター描画可能ファイルをプロジェクトに追加します。また、ビルド時に、Gradleはさまざまな解像度でPNGラスターイメージを作成します。 Gradleは、build.gradleファイルのDomain Specific Language(DSL)generatedDensitiesプロパティで指定されたPNG密度を生成します。 PNGを生成するには、ビルドシステムにAndroid Gradle 1.5.0以降のプラグインが必要です。

GradleにvectorDrawables.useSupportLibrary = trueを含める場合、これは当てはまりません。

falseに設定するか、ラインを完全に削除すると、すべてのベクターがそのまま機能します。ただし、古いバージョンのAndroidでは、変換されたPNGに依存できます

1
Thunderstick

フォームAndroid studio 3.0.0 Android:srcはベクター画像をサポートしておらず、21以下ではget例外が発生します。ベクターにはapp:srcCompatを使用しますimage。すべてのベクター画像ファイルをdrawableフォルダー内に保持します。

Android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 }

そして、アプリケーションクラスでこれを定義します。

@Override
public void onCreate() {
    super.onCreate();
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

これで、.xmlファイルを使用できます。このリンクを使用することを忘れないでください:xmlns:app = "http://schemas.Android.com/apk/res-auto"

<RelativeLayout
    Android:id="@+id/counterValuePanel"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >
    <ImageView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:srcCompat="@drawable/ic_cart_notify"/>
</RelativeLayout>

App:srcCompat = "@ drawable/ic_cart_notify"を使用できるようになりましたが、Android:backgroundまたはAndroid:drawableLeftで使用しようとすると、「エラーの膨張」例外が発生します。そのため、新しいラップされたドローアブル.xmlファイルを作成します。ic_cart_notifyはベクトルアイコンです。

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@drawable/ic_cart_notify"/>
</layer-list>
1

androidのtextviewでベクトルdrawableをside drawableに設定します

AppCompatTextViewnow サポートapp:drawableLeftCompatapp:drawableTopCompatapp:drawableRightCompatapp:drawableBottomCompatapp:drawableStartCompatおよびapp:drawableEndCompat複合ドロウアブル。VectorDrawableCompatなどのバックポートされたドロウアブルタイプをサポートします。

これをgradleファイルに含めます

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

テキストビューで使用できます

app:drawableLeftCompat
app:drawableStartCompat
0
Darish

大道は正しい。そのため、VectorDrawablesでビューにセレクターを使用する場合は、追加する必要があります。

    static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(trfor);
}

以下のバージョンのデバイスでVectorDrawablesを使用するすべてのアクティビティAndroid 5。

0
Djek-Grif