moagrius/TileView

Scale background

inneke-dc opened this issue · 9 comments

How can I set a background that scales as the tiles scale?
I have a low res image I want to show in the background while the tiles are loading. I set this on the 'container' view: tileView.container.background = lowResDrawable. This drawable is loaded with Glide and has the same size as the size being set on the tileview builder.
This looks okay for the start state (I can see the top left corner of the background image), but when I zoom, the background remains on the same (deepest) zoom level.

Try setting the background on the TileView itself. If that doesn't work, post back - I'll be doing some bug work tonight or tomorrow anyway so can include this

@moagrius Setting the background on the TileView itself causes it to always be in a completely zoomed out state and it doesn't pan or zoom, so it's actually a static background that way. Setting it on the container was slightly better in the way that it panned correctly, just the zoom level was fixed.

K. I'll check it out tonight

OK, there's a plugin for that.

You need a bitmap, so if you have something in res/drawable, you could do this:

Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.downsample, options);

Then in your builder, install it:

.installPlugin(new LowFidelityBackgroundPlugin(background))

e.g.,

Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.downsample, options);
new TileView.Builder(tileView)
        .setSize(17934, 13452)
        .defineZoomLevel("tiles/phi-1000000-%1$d_%2$d.jpg")
        .installPlugin(new LowFidelityBackgroundPlugin(background))
        .build();

I just tried that, but it's the same result as setting the low res image as background on the container: it doesn't scale. Looking into the code of LowFidelityBackgroundPlugin, I see that an ImageView is added to the container, so it's always the same size as the size provided to the TileView.Builder. No scale callbacks are handled.
I'll try to create my own plugin which scales the bitmap in the imageview, but no clue if this will work.

I got to a working solution!

class BackgroundPlugin(private val bitmap: Bitmap): TileView.Plugin, TileView.Listener {

    private lateinit var imageView: ImageView

    override fun install(tileView: TileView) {
        imageView = ImageView(tileView.context).apply {
            setImageBitmap(bitmap)
            scaleType = ImageView.ScaleType.MATRIX
        }

        tileView.addView(imageView, 0)
        tileView.addListener(this)
    }

    override fun onScaleChanged(scale: Float, previous: Float) {
        val scaleToFitImageView = imageView.width.toFloat() / bitmap.width
        val scaleToMatchZoom = scaleToFitImageView * scale

        val matrix = Matrix()
        matrix.setScale(scaleToMatchZoom, scaleToMatchZoom)
        imageView.imageMatrix = matrix
    }
}

Huh you're right! I'll modify your code and include it in the existing LowFidelityBackgroundPlugin class, and include that in the next update. Thanks again for contributing!

I've used a similar version to your fix, just slightly simplified. It's in the latest version as an update to LowFidelityBackgroundPlugin. Thanks again for the contribution.