bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.62k stars 6.12k forks source link

How to get a Drawable from glide? I want to use it in the default #4576

Open pcutting opened 3 years ago

pcutting commented 3 years ago

Kotlin, Android studio.

I'm at my wits end on trying to get a Drawable resource from glide for a exoPlayer defaultArtwork property.

From another post I see a method .asBitmap(). I'm guessing this has been removed? I'm trying to load an image from a string url.

(The following doesn't recognize .asBitmap() as a method for glide.

playerView?.defaultArtwork = Glide
                    .with(binding.root)
                    .load(story.storyThumbnail.url)
                    .asBitmap()

When I try to just go with .load, I get a type mismatch.

playerView?.defaultArtwork = Glide
                    .with(binding.root)
                    .load(story.storyThumbnail.url)

I'm getting:

Type mismatch. Required: Drawable? Found: RequestBuilder<Drawable!>

Not surprisingly when I try with .fallbackDrawable, nothing happens (no image is loaded).

                    .with(binding.root)
                    .load(story.storyThumbnail.url)
                    .fallbackDrawable

I'm sure that's not it's intended usage anyways.

Just to test, when I do the following it does load a default image:

playerView?.defaultArtwork = ContextCompat.getDrawable(
    this@PlayerActivity,
    R.drawable.the_last_hacker_cover
)

Reference: Similar to: https://github.com/bumptech/glide/issues/843

Glide V: implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' Gradle V: classpath "com.android.tools.build:gradle:4.1.3"

Video: (sorry if it's not very helpful) https://www.loom.com/share/7b2b40497e2342a7a4ac93b77543df3d

Activity code:

package com.philipcutting.markwahlbeck

import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.bumptech.glide.Glide
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ui.PlayerView
import com.google.android.exoplayer2.util.Util
import com.philipcutting.markwahlbeck.databinding.ActivityPlayerBinding
import com.philipcutting.markwahlbeck.models.Story
import com.philipcutting.markwahlbeck.viewmodels.PlayStoryViewModel
import com.philipcutting.markwahlbeck.viewmodels.StoryListViewModel

class PlayerActivity : AppCompatActivity() {

    companion object{
        private const val TAG = "PlayerActivity"
        private const val STORY_ID = "STORY_ID"
    }

    private lateinit var viewModel : PlayStoryViewModel
    private lateinit var binding: ActivityPlayerBinding

    private var playerView: PlayerView? = null
    private var player: SimpleExoPlayer? = null
    private var playWhenReady = true
    private var currentWindow = 0
    private var playbackPosition: Long = 0
    private var playbackStateListener: PlaybackStateListener? = null
    private lateinit var story : Story

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val storyId = intent.getStringExtra(STORY_ID)
        viewModel = ViewModelProvider(this).get(PlayStoryViewModel::class.java)
        binding = ActivityPlayerBinding.inflate(layoutInflater)

        if(!storyId.isNullOrEmpty()) {
            viewModel.getStoryFromTitle(storyId)
        }

        val storyObserver = Observer<Story?> { story ->
            Log.i(TAG, "test story from repo ---->> ${story?.storyTitle}")
            if(story != null) {
                val videoControl = binding.root.findViewById<View>(R.id.custom_player_control_view)
                //TODO lookup dataBindingUtil, commit first to preserve work.
                // val bindingLayoutPlayer = DataBindingUtil.
                //binding.videoView

                binding.videoView.findViewById<TextView>(R.id.file_label_tv).text = story.storyTitle

                binding.topAppBarBackOnlyMenu.title = story.storyTitle

                story.audioFiles.forEachIndexed { index, mediaResource ->
                    val mediaItem: MediaItem = MediaItem.fromUri(mediaResource.url)
                    if (index == 0) {
                        player?.setMediaItem(mediaItem)
                    } else {
                        player?.addMediaItem(mediaItem)
                    }
                }

//                playerView?.defaultArtwork = ContextCompat.getDrawable(
//                    this@PlayerActivity,
//                    R.drawable.the_last_hacker_cover
//                )

                playerView?.defaultArtwork = Glide
                    .with(binding.root)
                    .load(story.storyThumbnail.url)
                    .fallbackDrawable

                Log.i(TAG, "storyThumbnail: ${story.storyThumbnail.url}")
            }
        }

        viewModel.story.observe(this, storyObserver)

        //story = viewModel.getStoryFromTitle(storyId)

        binding.topAppBarBackOnlyMenu.title = "test"

        setContentView(binding.root)

        binding.topAppBarBackOnlyMenu.setOnMenuItemClickListener{ menuItem ->
            navigateWithMainMenu(menuItem)
        }

        playbackStateListener = PlaybackStateListener()
        playerView = binding.videoView
    }

    private fun initializePlayer() {
        if (player == null) {
            player = SimpleExoPlayer.Builder(this).build()
            playerView?.player = player
            player?.addListener(playbackStateListener!!)
        }

        player?.apply {

            this.playWhenReady = playWhenReady

            //Moving this from init to the onCreate.  Might want to move it back and not use
            // the liveData observer.  May not be needed at this point.
//            playerView?.defaultArtwork = ContextCompat.getDrawable(
//                this@PlayerActivity,
//                R.drawable.the_last_hacker_cover
//            )

            seekTo(currentWindow, playbackPosition)
            prepare()
        }
    }

    override fun onStart() {
        super.onStart()
        if (Util.SDK_INT >= 24) {
            initializePlayer()
        }
    }

    override fun onResume() {
        super.onResume()
        if (Util.SDK_INT < 24 || player == null) {
            initializePlayer()
        }
    }

    override fun onPause() {
        super.onPause()
        if (Util.SDK_INT < 24) {
            releasePlayer()
        }
    }

    override fun onStop() {
        super.onStop()
        if (Util.SDK_INT >= 24) {
            releasePlayer()
        }
    }

    private fun releasePlayer() {
        if (player != null) {
            player?.let {
                playWhenReady = it.playWhenReady
                playbackPosition = it.currentPosition
                currentWindow = it.currentWindowIndex
                it.removeListener(playbackStateListener!!)
                it.release()
            }
            player = null
        }
    }

    private class PlaybackStateListener : Player.EventListener {
        override fun onPlaybackStateChanged(state: Int) {
            val stateString: String = when (state) {
                ExoPlayer.STATE_IDLE -> "ExoPlayer.STATE_IDLE      -"
                ExoPlayer.STATE_BUFFERING -> "ExoPlayer.STATE_BUFFERING -"
                ExoPlayer.STATE_READY -> "ExoPlayer.STATE_READY     -"
                ExoPlayer.STATE_ENDED -> "ExoPlayer.STATE_ENDED     -"
                else -> "UNKNOWN_STATE             -"
            }
            Log.d(TAG, "changed state to $stateString")
        }
    }

    private fun navigateWithMainMenu(menuItem: MenuItem) = when (menuItem.itemId) {
        R.id.menu_back -> {
            navigateBack()
            true
        }
        else -> false
    }

    private fun navigateBack(key:String= "") {
        onBackPressed()
    }
}

Going to attach the gradle file here because it asnweres most of the questions on the setup.

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.firebase.firebase-perf'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.philipcutting.markwahlbeck"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    viewBinding.enabled = true
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

    implementation("androidx.recyclerview:recyclerview:1.2.0")
    // For control over item selection of both touch and mouse driven selection
    implementation("androidx.recyclerview:recyclerview-selection:1.1.0")

    implementation 'com.google.android.exoplayer:exoplayer-core:2.14.0'
    implementation 'com.google.android.exoplayer:exoplayer-dash:2.14.0'
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.14.0'

    implementation platform('com.google.firebase:firebase-bom:28.0.1')
    implementation 'com.google.firebase:firebase-analytics-ktx'
    implementation 'com.google.firebase:firebase-crashlytics-ktx'
    implementation 'com.google.firebase:firebase-perf-ktx'

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'

    implementation 'com.contentful.java:java-sdk:10.4.5'

    implementation 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

}
44667788 commented 3 years ago

You can get the Drawable by adding listener.

    Glide.with(this).load(R.mipmap.movie).listener(new RequestListener<Drawable>() {
      @Override
      public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target,
          boolean isFirstResource) {
        return false;
      }

      @Override
      public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target,
          DataSource dataSource, boolean isFirstResource) {
        Bitmap bitmap = ((BitmapDrawable)resource).getBitmap();
        return false;
      }
    }).into(imageView)