#android #firebase #picasso #firebaseui
#Android #firebase #пикассо #firebaseui
Вопрос:
Я использую пользовательский интерфейс Firebase с карточками RecyclerView, и на каждой карточке есть текст и небольшое изображение (90dp / 90dp). Я не загружаю изображения на устройство, я получаю URI изображения и, используя getDownloadUrl()
метод, получаю URL-адрес изображения и показываю его с помощью Picasso.
Проблема в том, что если в RecyclerView много записей, обновление изображений занимает некоторое время, если я прокручиваю страницу до нижней или верхней части.
Например, если я быстро прокручиваю страницу вниз, на секунду отображаются изображения, отображаемые в верхней части страницы, прежде чем показывать реальные изображения, которые должны быть там.
Я хочу знать, является ли загрузка изображений на устройство популярным способом быстрой загрузки изображений сегодня? Потому что я знаю, что некоторые приложения делают это.
Спасибо.
Комментарии:
1. используйте glide и кэшируйте изображения
2. Ваш вопрос в первую очередь основан на мнении . С учетом сказанного, почему бы просто не использовать изображение по умолчанию, которое будет отображаться в ожидании загрузки соответствующих изображений?
3. Знаете ли вы ответ, мистер ЭЛ?
Ответ №1:
Например, если я быстро прокручиваю страницу вниз, на секунду отображаются изображения, отображаемые в верхней части страницы, прежде чем показывать реальные изображения, которые должны быть там.
Причина, по которой вы видите старые изображения для новых мест, заключается в том, что RecylerView перерабатывает свои представления. Итак, к тому времени getDownloadUrl()
в следующем коде,
getDownloadUrl().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Picasso.with(context).
load(task.getResult())
into(holder.imageView);
}
});
разрешено ли предполагаемое представление, возможно, может быть переработано для отображения содержимого в другой позиции (в вашем случае при прокрутке вниз появляется новый элемент внизу списка).
В общем, будьте осторожны с использованием обратных вызовов для загрузки любых данных внутри onBindViewHolder
метода адаптеров просмотра recycler.
Я хочу знать, является ли загрузка изображений на устройство популярным способом быстрой загрузки изображений сегодня? Потому что я знаю, что некоторые приложения делают это.
Локальная загрузка содержимого изображения с последующим отображением действительно обеспечит наилучший пользовательский интерфейс, особенно если загружаемый контент не сильно меняется. Это также снизит ваши расходы на выставление счетов firebase, поскольку вам выставляется счет за загруженный ГБ. Но вам не нужно реализовывать это вручную.
Решение
Сначала используйте пользовательский обработчик запросов firebase для обработки URL-адресов хранилища firebase, например gs://somefirebasepath/somefile
. в этом load
методе реализована ваша логика кэширования.
import android.graphics.BitmapFactory;
import android.util.Log;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.StreamDownloadTask;
import com.squareup.picasso.Request;
import com.squareup.picasso.RequestHandler;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import static com.squareup.picasso.Picasso.LoadedFrom.NETWORK;
public class FirebasePicassoRequestHandler extends RequestHandler {
@Override
public boolean canHandleRequest(Request data) {
return data.uri != null amp;amp; "gs".equals(data.uri.getScheme();
}
@Override
public Result load(Request request, int networkPolicy) throws IOException {
//Implement your caching logic here, or load from network as follows
StorageReference gsReference = FirebaseStorage.getInstance().getReferenceFromUrl(request.uri.toString());
StreamDownloadTask mStreamTask;
InputStream inputStream ;
mStreamTask = gsReference.getStream();
try {
inputStream = Tasks.await(mStreamTask).getStream();
Log.i("FireBaseRequestHandler", "Loaded " gsReference.getPath() );
return new Result(BitmapFactory.decodeStream(inputStream), NETWORK);
} catch (ExecutionException e) {
throw new IOException();
} catch (InterruptedException e) {
throw new IOException();
}
}
}
И использовать Picasso.Builder
для создания экземпляра Picasso. И добавьте свой пользовательский обработчик в Picasso. При желании вы можете добавить прослушиватель ошибок, чтобы помочь отлаживать проблемы с обработчиком, если они возникают.
Picasso.Builder builder = new Picasso.Builder(this);
builder.addRequestHandler(new FirebasePicassoRequestHandler());
builder.listener(new Picasso.Listener() {
@Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
Log.e("Picasso", "Failure for " uri.toString(), exception);
}
});
Picasso.setSingletonInstance(builder.build());
Теперь нам больше не нужно разрешать URL-адреса хранилища firebase в вашем адаптере. Перед выполнением запроса на загрузку мы отменим все ожидающие запросы к нему, ImageView
а затем загрузим uri firebase следующим образом,
//inside your onBindViewHolder method
Picasso.with(context).cancelRequest(imageViewInstance);
Picasso.with(context)
.load("gs://somefirebase/imagefile")
.into(imageViewInstance);
а Пикассо справится с остальным.