web-dev-qa-db-ja.com

AppCompat 23.2は、API <21でRemoteViews(AppWidget)とともにVectorDrawableCompatを使用します

AppWidgetがあり、Lollipop以前のデバイスでもVectorDrawablesを使用したいと思います。 VectorDrawableCompatは、作成したRemoteViewでは機能しません。

アプリのAPKサイズを小さくするために、古いAPIプラットフォーム用のドロアブルの代替PNGバージョンを追加したくありません。

どうやってやるの?

29
araks

2017年10月22日更新

現在@ user924で述べているようにAppCompatDrawableManagerアクセスは独自のライブラリに制限されています。 ContextCompat.getDrawable(...)はトリックを行う必要があります。

2016年5月9日更新

@ kirill-kulakovの回答で述べたように、サポートライブラリの最新の更新では、TintContextWrapperの可視性が独自のパッケージに制限されていました。間違ったコードを削除するために回答を更新していますが、修正についてはキリルに感謝します!

VectorDrawableおよびRemoteViews pre-Lollipop

ベクター描画可能リソースの代替のラスタライズバージョンを追加することを避けることができます 簡単なhackで:AppCompatTintResourcesからTintContextWrapper使用AppCompatDrawableManager ContextCompatを使用します。

TintResourcesAppCompatDrawableManager ContextCompatは、特にLollipop以前のデバイスで、VectorDrawables XMLファイルを解析してVectorDrawableCompatインスタンス。API7まで使用できます。

次に、VectorDrawableCompatインスタンスを取得したら、それをビットマップにラスタライズします。後でこのビットマップをリモートImageViewで使用します。


始める前に:AppCompatライブラリ

Android Studio 2.0+を使用しており、アプリを設定していることを確認してくださいbuild.gradleファイルは次のとおりです。

Android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  compile 'com.Android.support:appcompat-v7:23.3.0'
}


AppWidgetProviderを更新する

まず第一に、RemoteViewsレイアウトファイル内にベクトル描画可能リソースを設定しないでください(Android:src nor app:srcCompat 働くでしょう)。プログラムで設定する必要があります。

AppWidgetProviderクラス内で、APIレベルに応じてベクターリソースまたはラスタライズバージョンを設定します。

RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
  remoteViews.setImageViewResource(R.id.imageView, R.drawable.vector);

} else {
  Drawable d = ContextCompat.getDrawable(context, R.drawable.vector);
  Bitmap b = Bitmap.createBitmap(d.getIntrinsicWidth(),
                                 d.getIntrinsicHeight(),
                                 Bitmap.Config.ARGB_8888);
  Canvas c = new Canvas(b);
  d.setBounds(0, 0, c.getWidth(), c.getHeight());
  d.draw(c);
  remoteViews.setImageViewBitmap(R.id.imageView, b);
}


参照資料

51
araks

次のメソッドは、vector drawableをビットマップに変換する前に、これでうまくいくはずです。

public static BitmapDrawable vectorToBitmapDrawable(Context ctx, @DrawableRes int resVector) {
    return new BitmapDrawable(ctx.getResources(), vectorToBitmap(ctx, resVector));
}

public static Bitmap vectorToBitmap(Context ctx, @DrawableRes int resVector) {
    Drawable drawable = AppCompatDrawableManager.get().getDrawable(ctx, resVector);
    Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
    drawable.draw(c);
    return b;
}
8
Kirill Kulakov