美文网首页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