flavioarfaria / KenBurnsView

Android ImageViews animated by Ken Burns Effect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does not play well if KenBurnsView size is changing

burningthumb opened this issue · comments

I was playing with this but found when the KenBurnsView size is being animated (I'm actually animating the weight of other views which is causing the KenBurnsView to resize) it goes kind of crazy. It seems the drawing does not take into account the fact that the KenBurnsView size has changed between frames :-(

So the problem is that the method onSizeChanged(int w, int h, int oldw, int oldh) is invoking the method reset() which in turn starts a new transition. This means, during an animation, a whole bunch of new transitions are fired. I think its better if OnSizeChanged just invokes updateViewport(width, height); with the new values. It works much better.

Here is how I changed it, maybe there is a better way?

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);

        //restart();
        handleResize();
    }
    private void handleResize()
    {
        int width = getWidth();
        int height = getHeight();

        if (width == 0 || height == 0) {
            return; // Can't call handleResize() when view area is zero.
        }

        updateViewport(width, height);

    }

Turns out scaling the viewport can result in the aspect ratio not matching which in turn results in a random transition being selected. This does not look good because there is a "jump" rather than a smooth transition back to the correct aspect ratio. The modified code for this follows:

  1. Don't throw an exception if the aspect ratio is wrong, let the transition run and at the end of the transition the aspect ration will be correct.
   public Transition(RectF srcRect, RectF dstRect, long duration, Interpolator interpolator)
    {
        // Scaling the viewport can result in 1 transition where the aspect ratio is not the same
        // but that's OK since this transition will fix it.  Throwing an exception that never gets
        // caught is simply not a good idea.

        // if (!MathUtils.haveSameAspectRatio(srcRect, dstRect))
        // {
        //      throw new IncompatibleRatioException();
        //}
  1. Don't generate a random transition if the aspect ratios don't match. Instead let the transition run and that will resync the aspect ratios.
        if (dstRect == null || drawableBoundsChanged)
        {
            srcRect = generateRandomRect(drawableBounds, viewport);
        }
        // A scaling of the viewport can result in the aspect ratio being out of symc and a new
        // random transiton results in a jump in the effect.  Instead just accept that the aspect ratio
        // is out of sync and let the transition take the aspect ratio back into sync.
        else if (viewportRatioChanged)
        {
            // The next transition will fix the aspect ratio so we can relax
            srcRect = dstRect;
        }
        else {
            /* Sets the destiny rect of the last transition as the source one
             if the current drawable has the same dimensions as the one of
             the last transition. */
            srcRect = dstRect;
        }