AppCompat 23.2在API <21上使用带有RemoteViews(AppWidget)的VectorDrawableCompat

我有一个AppWidget,我也想在它之前的棒棒糖设备中使用VectorDrawables。 VectorDrawableCompat不能与我创build的RemoteViews一起使用。

为了保持我的应用程序APK的大小,我不想为旧API平台添加我的drawable的替代PNG版本。

我怎样才能做到这一点?

  • 以编程方式从android中的vector更改fillColor
  • AnimatedVectorDrawable不会animation
  • 在android中以编程方式更改fillColor
  • 在运行时编程animation(VectorDrawable)animation
  • 我们可以使用VectorDrawable或VectorXML作为android中的推送通知的图标?
  • AppCompat 23.2在API <21上使用带有RemoteViews(AppWidget)的VectorDrawableCompat
  • VectorDrawable在API 23上无法正确呈现
  • 无效的可绘制标签vector
  • 更新22/10/2017

    正如@ user924所指出的那样, AppCompatDrawableManager访问被限制在它自己的库中。 ContextCompat.getDrawable(…)应该做的伎俩。

    更新05/09/2016

    正如@ kirill-kulakov在回答中所指出的那样,支持库的最新更新将TintContextWrapper的可见性限制在它自己的包中。 我正在更新我的答案,以删除不正确的代码,但请感谢基里尔的更正!

    VectorDrawable和RemoteViews之前的棒棒糖

    您可以避免通过简单的黑客手段添加vector可绘制资源的替代栅格化版本:使用 AppCompatDrawableManager,使用ContextCompat, 通过TintContextWrapper 使用AppCompat TintResources

    TintResources AppCompatDrawableManager ContextCompat是在Lollipop之前的设备中parsingVectorDrawable的XML文件并将其转换为VectorDrawableCompat实例的类,可以一直使用到API 7。

    然后,一旦你有一个VectorDrawableCompat实例,将其栅格化到一个位图上。 您稍后将在远程ImageView中使用此位图。

    开始之前:AppCompat库

    确保您使用的是Android Studio 2.0+,并已经configuration了您的应用程序build.gradle文件,如下所示:

     android { defaultConfig { vectorDrawables.useSupportLibrary = true } } dependencies { compile 'com.android.support:appcompat-v7:23.3.0' } 

    更新你的AppWidgetProvider

    首先:不要在你的RemoteViews布局文件中设置你的vector可绘制资源( android:srcapp:srcCompat都不会工作)。 你必须以编程方式设置它们。

    AppWidgetProvider类中,根据API级别设置vector资源或栅格化版本:

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

    参考

    • ContextCompat 源代码
    • Chris Banes的AppCompat v23.2 – vector博客文章的年龄介绍了VectorDrawableCompat,并解释了AppCompat用来使他们在前棒棒糖设备上工作的黑客。

    下面的方法将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; }