0

I am trying to create a progress bar that will display while an image is downloading from a server. This image is loaded into a custom view. (I need it to be custom because I draw on the image.)

My solution was to add the custom view into the XML under the layout of the fragment, and mark its visibility as Visibility.GONE. This worked in the XML editor, as the progress bar took up the full space. Invisible did not work as it's position was still displayed.

The issue comes when the image path is given to my custom view. It would seem that setting Visibility.GONE on a view means that the view is not measured. But I need the dimensions of the view to measure how large the bitmap should be.

// Create the observer which updates the UI.
       val photoObserver = Observer<String?> { photoPath ->


           spinner.visibility = View.GONE
           thumbnailFrame.visibility = View.VISIBLE

           thumbnailFrame.invalidate()

           thumbnailFrame.setImage(photoPath)

Looking at the Logs from the custom view, it is calling onMeasured() but it is doing it too late. I need onMeasure() to be called before setImage(). Is there a better way of handling this and if not is there a way to force the code to wait until I know the view has finished its measuring process?

1 Answer 1

0

Solved using a basic listener pattern with an anonymous class inline. I'm not sure if there is a better way but this way works just fine. Delay is not much of an issue since the view draws quite fast anyways.

     * Set a listener to notify parent fragment/activity when view has been measured
     */
    fun setViewReadyListener(thumbnailHolder: ViewReadyListener) {
        holder = thumbnailHolder
    }

    interface ViewReadyListener {

        fun onViewSet()
    }

    private fun notifyViewReadyListener() {
        holder?.onViewSet()
    }
            spinner.visibility = View.INVISIBLE
            thumbnailFrame.visibility = View.VISIBLE

            //We have to make sure that the view is finished measuring before we attempt to put in a picture
            thumbnailFrame.setViewReadyListener(object : ThumbnailFrame.ViewReadyListener {
                override fun onViewSet() {

                    thumbnailFrame.setImage(photoPath)

                    //If we have a previous saved state, load it here
                    val radius = viewModel.thumbnailRadius
                    val xPosit = viewModel.thumbnailXPosit
                    val yPosit = viewModel.thumbnailYPosit
                    if (radius != null) {
                        thumbnailFrame.setRadius(radius)
                    }
                    if (xPosit != null) {
                        thumbnailFrame.setRadius(xPosit)
                    }
                    if (yPosit != null) {
                        thumbnailFrame.setRadius(yPosit)
                    }
                }
            })
        }

Not the answer you're looking for? Browse other questions tagged or ask your own question.