美文网首页Android我爱编程
布局动画--LayoutTransition

布局动画--LayoutTransition

作者: 凯玲之恋 | 来源:发表于2018-04-10 18:53 被阅读144次
    LayoutTransition.png

    1 官网介绍-google翻译

    • 该类在ViewGroup对象的布局更改中启用自动动画
    • 要为布局容器启用transitions ,请创建一个LayoutTransition对象,并通过调用setLayoutTransition(LayoutTransition)将其设置在任何ViewGroup上。这会导致默认动画在items 添加到该容器或从该容器移除时运行。要指定自定义动画,请使用setAnimator()方法。
    • transition animations的核心概念之一是,导致转换的变化有两种类型,由于这些变化,有四种不同的动画会运行。
    • 触发transition 的更改是将items being added到容器(称为“出现”转换)或removed from容器(也称为“消失”)。设置views的visibility (在*GONEVISIBLE之间)将触发相同的添加/删除逻辑。
    • 由于这些事件而运行的动画是:1、添加items的动画,2、将被删除items的动画,3、添加/删除发生时更改的容器中的其他items的动画。
    • 使用transition 可能需要不同的动画来更改items,具体取决于他们是否因出现消失的事件而发生变化,因此对于这些变化事件的每个变体都有一个动画

    这个类的大部分API都关心如何设置中的任何一种或全部设置定制动画。

    • 默认情况下,DISAPPEARING(消失)和CHANGE_APPEARING(变化出现)动画立即开始。其他动画在延迟设置为默认的动画持续时间后开始。
      解释:
      当 item is being added to a layout时,该容器的其他子项将首先移动(从而为新项目创建空间),然后显示的动画将运行, item is being added;
      当tem is removed from a container时,要移除它的动画将首先运行,然后布局中其他子项的动画将运行(关闭在项目被移除时在布局中创建的间隙)。
    • 如果不需要此默认编排行为,则可以根据需要更改任何或所有动画的setDuration(int,long)和setStartDelay(int,long)。
    • 注意,如果在DISAPPEARING(消失)动画完成之前启动了APPEARING(显示)动画,则DISAPPEARING(消失)动画将停止,并且会恢复DISAPPEARING动画中的任何效果。如果您在显示动画完成之前启动DISAPPEARING(消失)动画,则会对APPEARING动画发生类似的一组效果。
    • 为transition 指定的动画(默认和在转换对象上设置的任何自定义动画)仅为模板。也就是说,这些动画存在的基本动画属性,如持续时间,启动延迟和属性bei

    2 Constants

    • APPEARING API11
      一个标志,子View添加到容器中时的过渡动画效果。画。
    • CHANGE_APPEARING API11
      一个标志,子View添加到容器中时,其他子View位置改变的过渡动画。
    • CHANGE_DISAPPEARING API11
      一个标志,子View从容器中移除时的过渡动画效果。
    • DISAPPEARING API11
      一个标志,子View从容器中移除时,其它子view位置改变的过渡动画
    • CHANGING API16
      一个标志,子View在容器中位置改变时的过渡动画,不涉及删除或者添加操作

    3 最简单的布局动画实现

    • 只要给子View所在的ViewGroup的xml中添加下面的属性即可:
    android:animateLayoutChanges="true"
    
    • 当ViewGroup在添加View时,子View会呈现出过渡的动画效果,这个动画效果是android默认的显示效果,而且无法使用自定义的动画来替换这个效果。

    4 LayoutTransition

    通过LayoutTransition就可以很容易为ViewGroup在添加或者删除子view设置自定义动画的过渡效果了。
    我们可以通过setLayoutTransition()方法为布局容器ViewGroup设置LayoutTransition对象,代码如下:

    LayoutTransition mTransitioner = new LayoutTransition();
    container.setLayoutTransition(mTransitioner);
    
    public class LayoutAnimationActivity extends Activity {
    
    
        private int i = 0;
        private LinearLayout container;
        private LayoutTransition mTransitioner;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_layout_animation);
    
            container = (LinearLayout) findViewById(R.id.container);
            
            mTransitioner = new LayoutTransition();
            
            container.setLayoutTransition(mTransitioner);
            setTransition();
        }
    
    
        private void setTransition() {
            /**
             * 添加View时过渡动画效果
             */
            ObjectAnimator addAnimator = ObjectAnimator.ofFloat(null, "rotationY", 0, 90,0).
                    setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));
            mTransitioner.setAnimator(LayoutTransition.APPEARING, addAnimator);
    
            /**
             * 移除View时过渡动画效果
             */
            ObjectAnimator removeAnimator = ObjectAnimator.ofFloat(null, "rotationX", 0, -90, 0).
                    setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));
            mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, removeAnimator);
    
            /**
             * view 动画改变时,布局中的每个子view动画的时间间隔
             */
            mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);
            mTransitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);
    
    
            /**
             *LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING的过渡动画效果
             * 必须使用PropertyValuesHolder所构造的动画才会有效果,不然无效!使用ObjectAnimator是行不通的,
             * 发现这点时真特么恶心,但没想到更恶心的在后面,在测试效果时发现在构造动画时,”left”、”top”、”bottom”、”right”属性的
             * 变动是必须设置的,至少设置两个,不然动画无效,问题是我们即使这些属性不想变动!!!也得设置!!!
             * 我就问您恶不恶心!,因为这里不想变动,所以设置为(0,0)
             *
             */
            PropertyValuesHolder pvhLeft =
                    PropertyValuesHolder.ofInt("left", 0, 0);
            PropertyValuesHolder pvhTop =
                    PropertyValuesHolder.ofInt("top", 0, 0);
            PropertyValuesHolder pvhRight =
                    PropertyValuesHolder.ofInt("right", 0, 0);
            PropertyValuesHolder pvhBottom =
                    PropertyValuesHolder.ofInt("bottom", 0, 0);
    
    
            /**
             * view被添加时,其他子View的过渡动画效果
             */
            PropertyValuesHolder animator = PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1);
            final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(
                    this, pvhLeft,  pvhBottom, animator).
                    setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING));
            
            mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);
    
    
            /**
             * view移除时,其他子View的过渡动画
             */
            PropertyValuesHolder pvhRotation =
                    PropertyValuesHolder.ofFloat("scaleX", 1, 1.5f, 1);
            final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(
                    this, pvhLeft, pvhBottom, pvhRotation).
                    setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING));
    
            mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);
        }
    
    
        public void addView(View view) {
            i++;
            Button button = new Button(this);
            button.setText("布局动画_" + i);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            container.addView(button, Math.min(1, container.getChildCount()), params);
        }
    
        public void removeView(View view) {
            if (i > 0)
                container.removeViewAt(0);
        }
    }
    

    注意
    在使用PropertyValuesHolder时,需要注意一下几点:

    • 1.LayoutTransition.CHANGE_APPEARING和LayoutTransition.CHANGE_DISAPPEARING必须使用PropertyValuesHolder构造动画才会有效果,其他任何方式构造动画都不会有效果。
    • 2.在使用PropertyValuesHolder时,”left”、”top”属性就算不需要变化也必须要写,如果不需要变化可以写成:
    PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 0);
    PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 0);
    
    • 3.ofInt,ofFloat中的参数值,第一个值和最后一个值必须相同,不然此属性所对应的的动画将被放弃,在此属性值上将不会有效果
    PropertyValuesHolder pvhTranslationY = PropertyValuesHolder
                .ofFloat("translationX", 0, 150, 0);
    
    • 4.使用的ofInt,ofFloat中,如果所有参数值都相同,也将不会有动画效果。
    PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 0);
    

    参考

    Android 布局动画之 animateLayoutChanges 与 LayoutTransition

    相关文章

      网友评论

      • Bo动:你好,请问setDuration()方法和setStagger()方法设置的时间不起作用是什么原因呢?

      本文标题:布局动画--LayoutTransition

      本文链接:https://www.haomeiwen.com/subject/mywnhftx.html