2013-11-24 2 views
66

Я использую Picasso для загрузки изображений для своего приложения.Использование Picasso для получения обратного вызова с битовой картиной

Я в ситуации, когда мне нужно получить доступ к Bitmap прежде, чем он будет загружен в ImageView. Наличие класса Downloader.Response, по-видимому, предполагает, что это возможно, но я не могу найти примеры использования. Я не хочу писать кучу больше кода, чтобы асинхронно обрабатывать этот конкретный случай, если это возможно с Picasso.

Может ли кто-нибудь показать мне, как это сделать?

+0

http://stackoverflow.com/a/36310327/ 5028508 – Killer

ответ

148

Найден ответ на GitHub в случае, если кто-то интересно:

private Target target = new Target() { 
     @Override 
     public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
     } 

     @Override 
     public void onBitmapFailed(Drawable errorDrawable) { 
     } 

     @Override 
     public void onPrepareLoad(Drawable placeHolderDrawable) { 
     } 
} 

private void someMethod() { 
    Picasso.with(this).load("url").into(target); 
} 

@Override 
public void onDestroy() { // could be in onPause or onStop 
    Picasso.with(this).cancelRequest(target); 
    super.onDestroy(); 
} 

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

+22

В идеале вы должны реализовать «Target» непосредственно на объекте вида или вида.Если вы этого не делаете, вам нужно поддерживать сильную ссылку на экземпляр где-нибудь, иначе он получит сбор мусора. –

+0

@JakeWharton: если я хочу применить пользовательскую анимацию для каждого элемента «ListView», вы предложите сделать что-то вроде: 'private static ViewHolder { private ImageView imageView; private Target target = new Target() { public void onBitmapLoaded() {// сделать анимацию на imageView} } } '? – mbmc

+0

@JakeWharton объясняет это здесь https://github.com/square/picasso/issues/308 в последнем комментарии. – toobsco42

-5

с использованием целевого сборщика мусора запустить свой plans.so я сделать трюк с этим примером кодом:

ImageView bitmapImageView = new ImageView(context); 
picasso.with(context).load(url).into(bitmapImageView); 
Bitmap bitmap = ((BitmapDrawable)bitmapImageView.getDrawable()).getBitmap(); 

Теперь вы можете наслаждаться вашим растровым; :))

+2

picasso.into это метод асинхронного, правильное решение может быть: picasso.with (контекст) .load (URL) .into (bitmapImageView, новый Callback() { @Override общественных недействительный OnSuccess() { Растровых растровыми = ((BitmapDrawable) bitmapImageView.getDrawable()). GetBitmap(); } public void onError() {} }); – luigi23

34

here взяты из:

Picasso.with(this) 
    .load(url) 
    .into(new Target() { 
     @Override 
     public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){ 
      /* Save the bitmap or do something with it here */ 

      //Set it in the ImageView 
      theView.setImageBitmap(bitmap); 
     } 
}); 

Обновлено (Май 04, 2016 г.):

  Picasso.with(this) 
       .load(youUrl) 
       .into(new Target() { 
        @Override 
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 

        } 

        @Override 
        public void onBitmapFailed(Drawable errorDrawable) { 

        } 

        @Override 
        public void onPrepareLoad(Drawable placeHolderDrawable) { 

        } 
       }); 

обновление (22 ноября, 2016)

или используя сильную ссылку на Target, чтобы он не собирался сбрасывать мусор

Target target = new Target() { 
      @Override 
      public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 

      } 

      @Override 
      public void onBitmapFailed(Drawable errorDrawable) { 

      } 

      @Override 
      public void onPrepareLoad(Drawable placeHolderDrawable) { 

      } 
     }; 


void foo() { 
     Picasso.with(getContext()).load(getUrl()).into(target); 
} 

Котлин

object: com.squareup.picasso.Target { 
        override fun onBitmapFailed(errorDrawable: Drawable?) { 
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
        } 

        override fun onPrepareLoad(placeHolderDrawable: Drawable?) { 
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
        } 

        override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { 

        } 
       } 
+2

Анонимная цель может быть сборщик мусора –

+0

@SteveM И что бы это сделать? Отменить запрос? Запретить загрузку растрового изображения? – nurettin

+0

@nurettin Я предполагаю, что Пикассо (или Глейд) имеет какую-то слабую ссылку на цель. Поэтому, если это анонимно, нет жесткой ссылки, и она уязвима для GC. Когда Picasso проверяет ссылку, она будет нулевой, поэтому обратный вызов не будет вызываться. –

2

Я думал, что, возможно, некоторые из вас хотели бы версию RxJava вышеуказанного ответа ... Вот оно:

public static Observable<Bitmap> loadBitmap(Picasso picasso, String imageUrl) { 
    return Observable.create(new Observable.OnSubscribe<Bitmap>() { 
     @Override 
     public void call(Subscriber<? super Bitmap> subscriber) { 
      Target target = new Target() { 
       @Override 
       public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
        subscriber.onNext(bitmap); 
        subscriber.onCompleted(); 
       } 

       @Override 
       public void onBitmapFailed(Drawable errorDrawable) { 
        subscriber.onError(new Exception("failed to load " + imageUrl)); 
       } 

       @Override 
       public void onPrepareLoad(Drawable placeHolderDrawable) { 
       } 
      }; 
      subscriber.add(new Subscription() { 
       private boolean unSubscribed; 

       @Override 
       public void unsubscribe() { 
        picasso.cancelRequest(target); 
        unSubscribed = true; 
       } 

       @Override 
       public boolean isUnsubscribed() { 
        return unSubscribed; 
       } 
      }); 
      picasso.load(imageUrl).into(target); 
     } 
    }); 
} 

P.S. При подключении, сохраните ссылку подписки на вашей деятельности, в противном случае, цель будет GC'd, прежде чем вы получите ответ ...

+0

Кажется, этот код сейчас не работает с последним RxAndroid – Pavandroid

0

Что может быть легче, чем следующая:

val url: String = "https://...." 
val bitmap: Bitmap = Picasso.with(context).load(url).get() 

Должен быть вызван из не основной поток!

или RxJava 2:

fun getBitmapSingle(picasso: Picasso, url: String): Single<Bitmap> = Single.create { 
    try { 
     if (!it.isDisposed) { 
      val bitmap: Bitmap = picasso.load(url).get() 
      it.onSuccess(bitmap) 
     } 
    } catch (e: Throwable) { 
     it.onError(e) 
    } 
} 

Retrieve Bitmap:

getBitmapSingle(Picasso.with(context), "https:/...") 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe({ bitmap -> 
       // val drawable = BitmapDrawable(context, bitmap) 
       }, Throwable::printStackTrace) 

Я использовал Пикассо v.2.5.2

 Смежные вопросы

  • Нет связанных вопросов^_^