Android Volley отображает SVG-изображение

В моем приложении для Android я загружаю текстовый контент со своего веб-сайта и сохраняю его в своей базе данных mysql. Теперь я хочу загружать и кэшировать изображения с того же сайта. С <com.android.volley.toolbox.NetworkImageView AndroidVolley загрузка обычных картинок работает довольно хорошо. Но я хочу загружать векторные изображения SVG, кэшировать их и отображать в своем приложении. Пока это невозможно в Android Volley...

Я уже пытался загрузить SVG с помощью AndroidVolley в виде строки, а затем поместить их в элемент svg-android (См. здесь), но svg-android никогда не показывал мое изображение. Кажется, он не может отображать SVG, созданные Inkscape...

Кто-нибудь знает простой способ, как загрузить эти файлы и отобразить их в представлении?

Спасибо

// ОБНОВЛЕНИЕ 27.03.2015 //

Итак, вот мое решение: с помощью Android Volley я установил StringRequest для доступа к моему SVG-изображению в виде строки. Библиотека AndroidSVG (не путайте с библиотекой svg-android) может преобразовать эту строку в SVG-объект и поместите его в SVGImageView-View. Вот пример кода, как это работало:

            StringRequest stringRequest = new StringRequest("http://******/image.svg",new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    try {
                        SVG svg = SVG.getFromString(response);
                        View view = getView();
                        if(view != null){
                            SVGImageView target = (SVGImageView)view.findViewById(catID);
                            target.setSVG(svg);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            },new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d(Globals.TAG,"Fehler "+error);
                }
            });
            RequestQueue queue = Volley.newRequestQueue(mContext);
            stringRequest.setShouldCache(true);
            queue.add(stringRequest);

Большое спасибо!


person Jokus    schedule 20.03.2015    source источник
comment
ты видел мой ответ?   -  person Y.S    schedule 20.03.2015
comment
Да спасибо. Я попробую ваш ответ в эти выходные ;-)   -  person Jokus    schedule 20.03.2015
comment
Я только что попробовал первый совет, но я никогда не мог видеть изображение... Таким образом, я получаю несколько записей Logcat, которые говорят мне, что в svg есть узлы, которые не могут быть отображены. Возможно, сгенерированные Inkscape SVG создают проблемы... Я поищу это позже и сообщу вам результат ;)   -  person Jokus    schedule 22.03.2015


Ответы (2)


Вы можете попробовать две вещи:

1. В библиотеке svg-android необходимо установить

imgView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

чтобы заставить его работать.

2. Если первый подход не работает, попробуйте использовать SVGImageView.

person Y.S    schedule 20.03.2015
comment
Первый совет не сработал, потому что svg-android явно не совместим с SVG, созданными в Inkscape. Но второй есть! Большое спасибо! - person Jokus; 27.03.2015
comment
Первый подход не специфичен для svg-android. Это относится к любой библиотеке, использующей определенные API Canvas. - person Paul LeBeau; 30.03.2015
comment
@PaulLeBeau: Верно, но это известная причина того, что изображения SVG не отображаются (если они не используются). - person Y.S; 30.03.2015

Вот немного другое решение, потому что я хотел сохранить загруженное изображение в переменной для повторного использования несколько раз.

Поэтому я просто изменил источник Volley, заменив «частный» на «защищенный» для метода.

protected Response <Bitmap> doParse (NetworkResponse response)

Затем я создал класс, наследуемый от ImageRequest и использующий библиотеку AndroidSVG.

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.widget.ImageView;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.ImageRequest;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;

/**
* Version modifiée de ImageRequest de Volley pour gérer aussi les images SVG
*/
public class MultiFormatImageRequest extends ImageRequest {

final String TAG = "EE." + getClass().getSimpleName();

boolean isSVG = false;

public MultiFormatImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
                               ImageView.ScaleType scaleType, Bitmap.Config decodeConfig, Response.ErrorListener errorListener) {
    super(url, listener, maxWidth, maxHeight, scaleType, decodeConfig, errorListener);
    String extension = url.substring(url.lastIndexOf("."));
    isSVG = (extension.toUpperCase().contains("SVG"));
}

/****
 * ATTENTION : "private" Response in Volley need to be changed in protected
 */
@Override
protected Response<Bitmap> doParse(NetworkResponse response) {
    Bitmap image = null;
    if (isSVG) {
        try {
            SVG svg = SVG.getFromString(new String(response.data));
            int h = (int) svg.getDocumentHeight();
            int w = (int) svg.getDocumentWidth();
            image = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);  // transparent
            Canvas bmcanvas = new Canvas(image);
            svg.renderToCanvas(bmcanvas);
        } catch (SVGParseException ex) {
            ex.printStackTrace();
        }

        if (image == null) {
            return Response.error(new ParseError(response));
        } else {
            return Response.success(image, HttpHeaderParser.parseCacheHeaders(response));
        }
    } else
        return super.doParse(response);  // Volley default
    }
}
person André DLC    schedule 26.12.2015