Search code examples
androidanimationviewbehaviorviewdraghelper

Android - Animate a view and change his real position (and another view follow with behavior dependency)


I'm trying to animate my appBar using a ViewDragHelper, when I drag it down it should start an animation and go down.

On top I have another view (pink in the example) that "follow" my appbar with a behavior (the top view depends on AppBarLayout).

As you can see here the appbar is animated but the "real" position do not change and, obviously, my top frame doesn't move.

In order to animate I use the following code:

@Override
public void onViewReleased(final View releasedChild, float xvel, float yvel) {
    super.onViewReleased(releasedChild, xvel, yvel);
    if (releasedChild.getTop() > childHeight) {
        Log.e("TAG", "SHOULD SCROLL " + releasedChild.getTop() + " > " + childHeight);
        final int offset = height - releasedChild.getTop() - 100;
        ViewCompat.animate(releasedChild).translationY(offset).setDuration(1000).setInterpolator(new OvershootInterpolator()).start();
    } else {
        Log.e("TAG", "SHOULD NOT SCROLL " + releasedChild.getTop() + " < " + childHeight);
        eleasedChild.offsetTopAndBottom(-releasedChild.getTop());
    }
    if (mDragFrameLayoutController != null) {
         mDragFrameLayoutController.onDragDrop(false);
    }
}

I've tried with many other animations:

TranslateAnimation scale = new TranslateAnimation(0.0f, 0.0f, 0.f, offset);
scale.setInterpolator(new OvershootInterpolator());
scale.setDuration(3000L);
scale.setFillEnabled(true);
scale.setFillAfter(true);
scale.setAnimationListener(new Animation.AnimationListener() {

or

ObjectAnimator moveY = ObjectAnimator.ofInt(releasedChild, "y", releasedChild.getTop(), offset);
AnimatorSet as = new AnimatorSet();
as.play(moveY);
as.start();

All these snippets give me the same result.

The only way I found to move the view is using offset but this doesn't animate, it just moves down...

releasedChild.offsetTopAndBottom(offset);

Any idea? Thanks.


Solution

  • I finally found the solution:

    on my viewDragHelper I overrode the following methods:

            @Override
            public int getViewVerticalDragRange(View child) {
                return getMeasuredHeight() - child.getMeasuredHeight();
            }
    
    
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                super.onViewReleased(releasedChild, xvel, yvel);
                if(yvel>0) {
                    mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getMeasuredHeight()-releasedChild.getMeasuredHeight());
                } else {
                    mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);
                }
                invalidate();
            }
    

    then on my custom view I overrode the following method:

       @Override
       public void computeScroll() {
           super.computeScroll();
           if (mDragHelper.continueSettling(true)) {
               ViewCompat.postInvalidateOnAnimation(this);
           }
       }
    

    And everything worked fine! I hope this can help someone in future.