Soru AppCompat 23.2 API <21 üzerindeki RemoteViews (AppWidget) ile VectorDrawableCompat kullanın


AppWidget'im var ve VectorDrawables'i de Lollipop öncesi cihazlarda kullanmak istiyorum. VectorDrawableCompat, oluşturduğum RemoteViews ile çalışmaz.

Uygulamamın APK boyutunu küçültmek için, eski API platformları için benim drawables'ımın alternatif PNG sürümlerini eklemek istemiyorum.

Bunu nasıl yapabilirim?


25
2018-02-25 16:50


Menşei




Cevaplar:


GÜNCELLEME 22/10/2017

@ User924 tarafından belirtildiği gibi AppCompatDrawableManager erişim kendi kütüphanesi ile sınırlıdır. ContextCompat.getDrawable (...) hile yapmalı.

GÜNCELLEME 05/09/2016

Yanıt olarak @ kirill-kulakov tarafından belirtildiği gibi, Destek Kitaplığı'nın en son güncellemeleri TintContextWrapper görünürlüklerini kendi paketine sınırladı. Yanlış kodu kaldırmak için cevabımı güncelleştiriyorum, ancak düzeltme için Kirill'e teşekkür edin!

VectorDrawable ve RemoteViews öncesi Lollipop

Vektör çekilebilir kaynaklarınızın alternatif rasterleştirilmiş sürümlerini eklemekten kaçınabilirsiniz. kolay kesmek: AppCompat kullan TintResources vasitasiyla TintContextWrapper  kullanma AppCompatDrawableManager kullanma ContextCompat.

TintResources  AppCompatDrawableManager  ContextCompat Lollipop öncesi cihazlarda, diğer şeylerin yanı sıra VectorDrawables XML dosyalarını VectorDrawableCompat API 7'ye kadar tüm yollarla kullanılabilecek örnekler.

Sonra, bir kez VectorDrawableCompat Örneğin, bir Bitmap üzerine rasterleştirin. Daha sonra bu bitmapi bir uzaktan kumandada kullanacaksınız. Resim görünümü.


Başlamadan önce: AppCompat Kütüphanesi

Android Studio 2.0+ sürümünü kullandığınızdan ve uygulamanızı yapılandırdığınızdan emin olun. build.gradle aşağıdaki gibi dosya:

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

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


AppWidgetProvider'ınızı güncelleyin

Her şeyden önce: Vektör çizilebilir kaynaklarınızı kendi RemoteViews düzen dosyası (ne ikisi de android:src ne de app:srcCompat çalışacak). Onları programlı olarak ayarlamanız gerekecek.

Senin içinde AppWidgetProvider sınıf, API düzeyine bağlı olarak vektör kaynağını veya rasterleştirilmiş bir sürümü ayarlayın:

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


Referanslar


45
2018-02-25 16:50



TintContextWrapper android.support.v7.widget içinde herkese açık değildir; dış paketten erişilemiyor - Kirill Kulakov
hata Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);  stackoverflow.com/questions/43710994/... - user25
AppCompatDrawableManager can only be called from within the same library group - user924
Merhaba @ user924, en son Android Destek Kitaplığı sürümlerine uyumluluk eklemek için cevabı güncelledim! Teşekkür ederim! - araks
As noted by @user924 now AppCompatDrawableManager access is restricted to its own library. a) Bu aslında onu kullanmasını engellemez. b) Şu anda herkese açık API var AppCompatResources.getDrawable(...). - Eugen Pechanec


Aşağıdaki yöntem, vector drawable Daha önce bir bitmap için, bu hile yapmalıdır.

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
2018-05-08 08:10