Как реализовать GlideApp во фрагменте? - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь получить изображение из хранилища Firebase внутри фрагмента с kotlin, но он просто не работает. Вот код:

val data = FirebaseStorage.getInstance()
val storageRef = data.getReference()
val pathReference = storageRef.child(user.uid.toString() + "/images/coverphoto/")

GlideApp.with(context)
     .load(pathReference)
     .into(view.profileUserCoverPhoto)

Это дает мне ошибку: Required: Context Found: Context?

Я также пытался GlideApp.with(this@Profile) и GlideApp.with(view.context) (я надуваю свое мнение на view, поэтому я пытался это сделать. Я не могу понять, каким должен быть контекст, и я считаю, что это проблема. Изображение загружено в Firebase просто отлично, поэтому я знаю, что он есть. Я считаю, что ошибка связана с моим глиссадным кодом. В частности, с частью кода context, но я не знаю, что я делаю неправильно или что мне следует использовать. Любая помощь будет оценены.

***** ****** Update 1013 *

Я только что проверил Glide с URL из Интернета, и он работает просто отлично. Я также только что протестировал с URL-адресом firebase к изображению "https://firebasestorage.googleapis.com/v0/b/cyber-chatter.appspot.com/o/8YiLlLOxRgO2FjF9OSUKBeL7ckn2%2Fimages%2Fcoverphoto?alt=media&token=7876830c-393f-4a00-be61-80fbd775cf28", и это тоже прекрасно работает. Я перебрал свой pathReference и он правильно строит.

Это сбивает с толку и расстраивает. Я пытался найти решение в течение 3 дней. Понятия не имею, что я делаю не так ...

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

В kotlin тип данных может быть Nullable или Non-Nullable. Чтобы пометить как обнуляемый, мы используем знак вопроса. Это не Nullable

var c: Context // Equivalent to @NonNullable Context c;

Это Nullable

var c: Context? // Equivalent to @Nullable Context c;

Теперь для вашего GlideApp необходим ненулевой контекст. Но ваш метод getContext для фрагментов может вернуть значение null. Так. Давайте посмотрим на этот метод.

  /**
    * Return the {@link Context} this fragment is currently associated with.
    *
    * @see #requireContext()
    */
    @Nullable
    public Context getContext() {
        return mHost == null ? null : mHost.getContext();
    }

    @Nullable
    final public FragmentActivity getActivity() {
        return mHost == null ? null : (FragmentActivity) mHost.getActivity();
    }

Таким образом, вы можете получить значение NULL, если фрагмент не привязан к действию. По сути, вы можете быть уверены, что контекст не равен нулю между onAttach фрагмента и методом onDetach.

Таким образом, между ними, как в onCreate, вы можете использовать ненулевое утверждение

GlideApp.with(getContext()!!)

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

getContext()?.let{ GlideApp.with(it) ... }  

https://developer.android.com/images/fragment_lifecycle.png

0 голосов
/ 05 сентября 2018

Наконец !! Я разобрался с вопросом:

Мой требуемый AppGlideModule.kt был неверным. Для котлина это должно выглядеть так:

import android.content.Context
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import com.google.firebase.storage.StorageReference
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
import com.firebase.ui.storage.images.FirebaseImageLoader
import java.io.InputStream
import com.google.firebase.FirebaseOptions.Builder



@GlideModule
class RequiredAppGlideModule : AppGlideModule() {

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        // Register FirebaseImageLoader to handle StorageReference
        registry.append(StorageReference::class.java, InputStream::class.java,
                FirebaseImageLoader.Factory())
    }
}

Как только я сделал это и добавил все правильные ссылки на импорт, показанные выше, я получил неизвестную ошибку ссылки для FirebaseImageLoader, поэтому я также создал класс FirebaseImageLoader.kt, используя этот код:

<code>package com.firebase.ui.storage.images

import android.util.Log    
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.Key
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.google.android.gms.tasks.OnFailureListener
import com.google.android.gms.tasks.OnSuccessListener
import com.google.firebase.storage.StorageReference
import com.google.firebase.storage.StreamDownloadTask

import java.io.IOException
import java.io.InputStream
import java.nio.charset.Charset
import java.security.MessageDigest

/**
 * ModelLoader implementation to download images from FirebaseStorage with Glide.
 *
 *
 *
 * First, register this class in your AppGlideModule:
 * <pre>
 * @Override
 * public void registerComponents(Context context, Registry registry) {
 * // Register FirebaseImageLoader to handle StorageReference
 * registry.append(StorageReference.class, InputStream.class,
 * new FirebaseImageLoader.Factory());
 * }
* * * * * Затем загрузите StorageReference в ImageView. *
 * StorageReference ref = FirebaseStorage.getInstance().getReference().child("myimage");
 * ImageView iv = (ImageView) findViewById(R.id.my_image_view);
 *
 * GlideApp.with(this)
 * .load(ref)
 * .into(iv);
* * / Класс FirebaseImageLoader: ModelLoader { / ** * Фабрика для создания [FirebaseImageLoader]. * / Фабрика класса: ModelLoaderFactory { переопределить забавную сборку (фабрика: MultiModelLoaderFactory): ModelLoader { вернуть FirebaseImageLoader () } переопределить веселый разрыв () { // Нет операции } } переопределить весело buildLoadData (ссылка: StorageReference, высота: Int, ширина: Int, Параметры: Параметры): ModelLoader.LoadData ? { return ModelLoader.LoadData ( FirebaseStorageKey (ссылка), FirebaseStorageFetcher (ссылка)) } переопределить забавные дескрипторы (ссылка: StorageReference): Boolean { вернуть истину } закрытый класс FirebaseStorageKey (закрытый val mRef: StorageReference): Key { переопределить забавный updateDiskCacheKey (digest: MessageDigest) { digest.update (mRef.path.toByteArray (Charset.defaultCharset ())) } } закрытый класс FirebaseStorageFetcher (закрытый val mRef: StorageReference): DataFetcher { приватная переменная mStreamTask: StreamDownloadTask? = ноль приватная переменная mInputStream: InputStream? = ноль переопределить веселье loadData (приоритет: приоритет, обратный вызов: DataFetcher.DataCallback ) { mStreamTask = mRef.stream mStreamTask !! .addOnSuccessListener {снимок -> mInputStream = snapshot.stream callback.onDataReady (mInputStream) } .addOnFailureListener {e -> callback.onLoadFailed (e)} } переопределить веселую очистку () { // Закрыть поток, если это возможно if (mInputStream! = null) { пытаться { mInputStream !!. закрыть () mInputStream = null } catch (e: IOException) { Log.w (TAG, «Не удалось закрыть поток», e) } } } переопределить удовольствие отменить () { // Отмените задачу, если это возможно if (mStreamTask! = null && mStreamTask !!. isInProgress) { mStreamTask !!. отмена () } } переопределить веселье getDataClass (): Class { return InputStream :: class.java } переопределить веселье getDataSource (): DataSource { вернуть DataSource.REMOTE } } сопутствующий объект { private val TAG = "FirebaseImageLoader" } }

Затем я импортировал это в свой requiredAppGlideModule.kt, и как только я сделал эти две вещи, изображение загрузилось без проблем! Ура!

0 голосов
/ 05 сентября 2018

Ваша ошибка компиляции:

Обязательно: контекст найден: контекст?

Это связано с тем, что метод Fragment.getContext () аннотирован @Nullable. Если фрагмент не прикреплен, он вернет ноль.

context?.let { // If context is not null use it in the passed block as `it`
    GlideApp.with(it)
         .load(pathReference)
         .into(view.profileUserCoverPhoto) 
}

См .: https://kotlinlang.org/docs/reference/null-safety.html или Котлин в действии 6.1 https://www.manning.com/books/kotlin-in-action

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...