Пусть Volley's NetworkImageView показывает локальные файлы изображений

Я использую NetworkImageView чтобы показать некоторые обложки, загруженные с удаленного URL-адреса, и я успешно могу кэшировать и показывать их, но я хочу позволить пользователям устанавливать свои собственные изображения обложек, если они хотят. Я пытался использовать setImageUrl метод с Uri.fromFile(mCoverFile).toString() в качестве аргументов, но это не работает. Поскольку это сочетание удаленных и локальных изображений, я не могу переключиться на обычные ImageViews, так что мне было интересно, есть ли способ включить загрузку локальных изображений.

Я конечно знаю о ImageView"s setImageBitmap метод, но NetworkImageView автоматически изменяет размер созданного Bitmap а также предотвращает View переработка в GridViewс и ListViews.

ОБНОВЛЕНИЕ: njzk2. Чтобы автоматически изменить размер растрового изображения в соответствии с вашим View размер, затем просто скопируйте ImageRequest.doParse метод из источника Волли.

3 ответа

Решение

NetworkImageView использования ImageLoaderкоторый в свою очередь использует ImageCache,

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

 return new StringBuilder(url.length() + 12).append("#W").append(maxWidth)
            .append("#H").append(maxHeight).append(url).toString();

url не проверяется до того, как будет выполнен фактический запрос, поэтому здесь нет проблем.

Как правило, ваш "кеш" может выглядеть так:

public class MyCache implements ImageLoader.ImageCache {

    @Override
    public Bitmap getBitmap(String key) {
        if (key.contains("file://")) {
            return BitmapFactory.decodeFile(key.substring(key.indexOf("file://") + 7));
        } else {
            // Here you can add an actual cache
            return null;
        }
    }
    @Override
    public void putBitmap(String key, Bitmap bitmap) {
        // Here you can add an actual cache
    }
}

Вы используете это как:

imageView.setImageUrl(Uri.fromFile(mCoverFile).toString(), new MyCache());

(Это на самом деле не было проверено и может потребоваться внести некоторые коррективы)

Спасибо за ваш ответ. Я написал код, основанный на вашей помощи.

Использование: просто используйте LocalImageCache.class в качестве Cache. Нет больше кода для изменения.

private ImageLoader mLocalImageLoader;

mLocalImageLoader = new ImageLoader(mRequestQueue,
            new LocalImageCache(mCtx));

NetworkImageView test = (NetworkImageView) findViewById(R.id.iv_test);  

test.setImageUrl("/storage/emulated/0/DCIM/Philm/2017_03_24_01_.png", MySingleton.getInstance(this.getApplicationContext()).getLocalImageLoader());

public class LocalImageCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {

public LocalImageCache(int maxSize) {
    super(maxSize);
}

public LocalImageCache(Context ctx) {
    this(getCacheSize(ctx));
}

@Override
public Bitmap getBitmap(String key) {
    key = key.substring(key.indexOf("/"));
    Bitmap result = get(key);
    Log.d("TAG", key);
    if (result == null) {
        Bitmap temp =  BitmapFactory.decodeFile(key);
        put(key, temp);
        return temp;
    } else {
        return result;
    }
}

@Override
public void putBitmap(String key, Bitmap bitmap) {
    // Here you can add an actual cache
    // Never touch here
}

// 默认屏幕5倍的图片缓存
// Returns a cache size equal to approximately three screens worth of images.
public static int getCacheSize(Context ctx) {
    final DisplayMetrics displayMetrics = ctx.getResources().
            getDisplayMetrics();
    final int screenWidth = displayMetrics.widthPixels;
    final int screenHeight = displayMetrics.heightPixels;
    // 4 bytes per pixel
    final int screenBytes = screenWidth * screenHeight * 4;

    return screenBytes * 5;
}

@Override
protected int sizeOf(String key, Bitmap value) {
    return value.getRowBytes() * value.getHeight();
}

}

NetworkImageView расширяет ImageView. Вы должны быть в состоянии использовать те же методы, что и обычный ImageView

image.setImageResource(R.drawable.my_image);

или же

imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath)); 
Другие вопросы по тегам