在Android 3.0及以上版本中,使用相同的代码SVG图像不可见。

10

我有一个测试应用程序,其中有一个ListView,其中包含两个图像。

nexus 7 vs. desire hd

正如您在API 17设备中所看到的那样,它不显示播放按钮(SVG图像),而API 10设备却显示。我该如何解决这个问题?

我的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/background"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/forceground"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

这是我的基本代码,我在其中设置了图像:

View preview = inflater.inflate(R.layout.list_video_preview, parent, false);
ImageView background = (ImageView)preview.findViewById(R.id.background);
ImageView forceground = (ImageView)preview.findViewById(R.id.forceground);
PictureDrawable play = SVGParser.getSVGFromResource(parent.getResources(), R.raw.play_blue).createPictureDrawable();
forceground.setImageDrawable(play);

SVG解析器来自svg-android


1
你在哪里设置背景ImageView? - Villan
通过一个复杂的回调函数,从网络上下载图像。假设我不相信这会导致问题。 - rekire
2个回答

17

问题在于硬件加速。解决方法是使用位图而不是可绘制对象。为了修复这个问题,我在SVG.java中添加了这个函数,它返回一个BitmapDrawable

public BitmapDrawable createBitmapDrawable(Context context) {
    Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    PictureDrawable drawable = new PictureDrawable(picture);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return new BitmapDrawable(context.getResources(), bitmap);
}

很棒,除了它会导致缩放问题。但对于常规低强度使用来说还是可以的。 - Evan Leis

15
你的解决方案存在问题,将其转换为Bitmap时会丢失所有绘图信息。在你的情况下不适用,但如果需要支持ZoomingPanning,则需要缩放和调整Bitmap,这将导致像素化的图形。此外,将Picture绘制到将包含它的View中的Bitmap中,效率更低。

我遇到了与你相同的问题,并通过仅在将绘制Picture的视图上关闭硬件加速来解决它:

view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

然而,setLayerType 仅支持 API 11 及以上版本。因此,请使用以下方法代替:

public static void setHardwareAccelerated(View view, boolean enabled){
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
        if(enabled)
            view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        else view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }
}

1
最好使用类似于 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 的方式来检查API是否存在。我需要检查一下。 - rekire
是的,没错。我使用了我看到的一个例子中的代码,没有记住它会这么简单 ;) 谢谢,当我测试后会更改我的答案。 - ffleandro
1
+1 这个答案避免了模糊不清的情况,与被接受的答案不同,因为在 GridView 适配器中膨胀的 ImageView 等情况下,可能事先不知道画布的大小。 - pqn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接