3 pane layout fragment animation is stuttering

后端 未结 2 2072
温柔的废话
温柔的废话 2020-12-28 11:22

The implementation info: I have implemented a 3 pane layout following CommonsWare response posted on his own question over here: Complete Working Sample of

相关标签:
2条回答
  • 2020-12-28 11:37

    I ended up removing the ObjectAnimator completely... It still has the slide animation, of course, but not the smooth re-dimensioning at the same time. Not that it was actually smooth...

    Anyway, if somebody does come up with an actual solution to this problem, feel free to share. Thanks.

    package com.anfuddle.view.widget;
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.os.Build;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewPropertyAnimator;
    import android.widget.LinearLayout;
    
    
    public class ThreePaneLayout extends LinearLayout
    {
        private View leftView = null;
        private View middleView = null;
        private View rightView = null;
    
    private static final int ANIM_DURATION = 500;
    private int rootWidth = -1;
    private int leftPaneWidth = -1;
    private int rightPaneWidth = -1;
    
    
    // -------------------------------------------------------------------------------------------
    // --------------   Constructor
    // -------------------------------------------------------------------------------------------
    
    
    public ThreePaneLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        setOrientation(HORIZONTAL);
    }
    
    @Override
    public void onFinishInflate()
    {
        super.onFinishInflate();
    
        leftView = getChildAt(0);
        middleView = getChildAt(1);
        rightView = getChildAt(2);
    }
    
    
    // -------------------------------------------------------------------------------------------
    // --------------   Public methods
    // -------------------------------------------------------------------------------------------
    
    
    public View getLeftView()
    {
        return leftView;
    }
    
    public View getMiddleView()
    {
        return middleView;
    }
    
    public View getRightView()
    {
        return rightView;
    }
    
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void hideLeftAndMiddle()
    {
        if (leftPaneWidth == -1)
        {
            rootWidth = getWidth();
            leftPaneWidth = leftView.getWidth();
            rightPaneWidth = middleView.getWidth();
        }
        resetWidget(leftView, leftPaneWidth);
        resetWidget(middleView, rightPaneWidth);
        resetWidget(rightView, rootWidth);
        requestLayout();
    
        translateWidgets(-1 * rootWidth, leftView, middleView, rightView);
    }
    
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void hideLeft()
    {
        if (leftPaneWidth == -1)
        {
            leftPaneWidth = leftView.getWidth();
            rightPaneWidth = middleView.getWidth();
        }
        resetWidget(leftView, leftPaneWidth);
        resetWidget(middleView, leftPaneWidth);
        resetWidget(rightView, rightPaneWidth);
        requestLayout();
        translateWidgets(-1 * leftPaneWidth, leftView, middleView, rightView);
    }
    
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void showLeftAndMiddle()
    {
        translateWidgets(rootWidth, leftView, middleView, rightView);
    }
    
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void showLeft()
    {
        resetWidget(leftView, leftPaneWidth);
        resetWidget(middleView, rightPaneWidth);
        resetWidget(rightView, rightPaneWidth);
        requestLayout();
        translateWidgets(leftPaneWidth, leftView, middleView, rightView);
    }
    
    
    // -------------------------------------------------------------------------------------------
    // --------------   Private methods
    // -------------------------------------------------------------------------------------------
    
    
    @TargetApi(12)
    private void translateWidgets(int deltaX, View... views)
    {
        for (final View view : views)
        {
            ViewPropertyAnimator viewPropertyAnimator = view.animate();
            viewPropertyAnimator.translationXBy(deltaX)
                                .setDuration(ANIM_DURATION);
        }
      }
    
      private void resetWidget(View view, int width)
      {
          LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)view.getLayoutParams();  
          layoutParams.width = width;
          layoutParams.weight = 0;
      }
    }
    
    0 讨论(0)
  • 2020-12-28 11:42

    The problem is not ObjectAnimator, but rather that your application is simply doing too much on every frame of the animation. Specifically, you are animating layout params and requesting layout on every frame. Layout is powerful and useful... but can be quite expensive in any but the most trivial of view hierarchies. It's important to avoid expensive operations per-frame during animations, and layout falls into that "expensive" category. Sliding things around is fine (translationX/Y), fading things in/out is good (alpha), but actually laying things out on every frame? Just say no.

    0 讨论(0)
提交回复
热议问题