alexvasilkov / GestureViews

ImageView and FrameLayout with gestures control and position animation
Apache License 2.0
2.37k stars 384 forks source link

Animating height/width resets state #173

Closed imnadev closed 2 years ago

imnadev commented 3 years ago

Hi

I have a gesture image view with crop area view inside a card view matching its height and weight. When user changes aspect ratio of crop, I animate the card view dimensions like below to match the ratio

fun CardView.widthAnim(w1: Int, w2: Int) = 
    ValueAnimator.ofInt(w1, w2).apply {
        duration = 500L
        addUpdateListener {
            layoutParams = layoutParams.apply { width = it.animatedValue as Int }
        }
        start()
    }

As the animation starts gesture image view state resets: zoom, pan, rotation just goes back to original. How can I keep them intact while changing the parent width/height?

alexvasilkov commented 3 years ago

When view size is changed the image state have to be recalculated (e.g. min zoom can be affected; the image is positioned relative to top-left corner so it's positioned will change as well). We also have to reset the state to initial because it can take few passes to calculate view's actual size and we want the view to end up in its initial state.

In your case you have to calculate the final image state manually and update it along the way somehow. I don't think it will be easy to sync it with re-layout process (which will reset the state), you may try to use getViewTreeObserver().addOnPreDrawListener(...) to apply desired state before the image is drawn. You can try to use fixed GestureImageView size and only animate the card view size, while the image view will just be cetnered and cropped inside it without actually changing its size.

Overall I'm not sure that animating the view height like this is a good approach, as it can be quite slow and inefficient. Maybe try LayoutTransition?