Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG image not visible in android 3.0+ with same code

I have a test app where I have got a ListView with an item which contains two images on it.

nexus 7 vs. desire hd

As you can see in the API 17 device does not display the play button (SVG image) while the API 10 device does that. How can I fix that?

My layout file:

<?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>

Here is my basic code where I set the images:

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

The SVG paser is from svg-android.

like image 678
rekire Avatar asked Dec 21 '12 09:12

rekire


2 Answers

The problem is the hardware acceleration. The solution is to use bitmaps instad of drawables. For fixing that I added this function to the SVG.java which returns a 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);
}
like image 72
rekire Avatar answered Nov 15 '22 12:11

rekire


The problem with your solution is that you are losing all the drawing information when converting it to a Bitmap. In your case it doesn't apply, but if you needed to support Zooming and Panning, you would be scaling and resizing a Bitmap and would get pixelated graphics. Additionally it's much more inefficient to draw a Picture into a Bitmap which will then be drawn by the View that contains it.

I had the same problem you experienced and solved it by turning off hardware acceleration only on the view that will draw the Picture:

view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

However setLayerType is only supported since API 11. So use this method instead:

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);
    }
}
like image 15
ffleandro Avatar answered Nov 15 '22 10:11

ffleandro