Android布局动画--LayoutTransition

来源:互联网 发布:php企业网站 编辑:程序博客网 时间:2024/05/17 06:01

1、简介

我在我的博客Android–LayoutAnimation介绍中介绍了布局动画,所谓布局动画就是对 ViewGroup 这样的容器去做动画,而不是像补间动画这样只处理某一个View对象。

那篇博客中我着重讲了 LayoutAnimationController 这个类,它是用来指定一个应用到 ViewGroup 的每个子View的动画。

这里我要讲讲 LayoutTransition 这个类,在Android应用开发的时候经常会用到View的setVisibility()方法来动态隐藏和显示view,但是这样子是没有过渡动画的,变化的时候会显得很生硬。

而 LayoutTranstion 类用于当前布局容器中有View添加,删除,隐藏,显示的时候定义布局容器自身的动画和View的动画。也就是说当一个LinerLayout中隐藏一个view的时候,我们可以自定义整个LinerLayout容器因为隐藏了view而改变的动画,同时还可以自定义被隐藏的view自己消失时候的动画。你可以先实例化一个LayoutTransition对象,通过setLayoutTransition()方法将对象设置进一个布局容器ViewGroup中去。

private LinearLayout container;private LayoutTransition mTransitioner;               .               .               .   mTransitioner = new LayoutTransition();container.setLayoutTransition(mTransitioner);

此外还有一个更简单地使用方法,在xml文件中我们在容器的中下面一句代码:

android:animateLayoutChanges="true"

这样,每当有子view从容器中出现或消失的时候,默认的animator就会被自动调用。当然,我们也可以通过setAnimator()来设置自定义的动画。

2、LayoutTransition

LayoutTransition类定义了如下几种布局容器动画类型:

  • APPEARING :当view出现或者添加的时候,view出现的动画
  • DISAPPEARING :当view消失或者隐藏的时候,view消失的动画
  • CHANGE_APPEARING :当添加view导致布局容器改变的时候,整个布局容器的动画
  • CHANGE_DISAPPEARING :当删除或者隐藏view导致布局容器改变的时候,整个布局容器的动画
  • CHANGE:当不是由于View出现或消失造成对其他View位置改变的时候整个布局容器的动画

3、LayoutTransition使用

这里我写个例子介绍一下 LayoutTranstion 在代码中的具体使用,演示 LayoutTransition 各种动画框架的效果。

1、基本使用

public class LayoutTransitionActivity extends AppCompatActivity {    private ViewGroup viewGroup;    private GridLayout mGridLayout;    private LayoutTransition mTransition;    private int count = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_layout_transition);        viewGroup = (ViewGroup) findViewById(R.id.container);        mGridLayout = new GridLayout(this);        mGridLayout.setColumnCount(5);        viewGroup.addView(mGridLayout);        // 默认动画全部开启         mTransition = new LayoutTransition();        mGridLayout.setLayoutTransition(mTransition);    }    public void addView(final View view) {        final Button button = new Button(this);        button.setText(++count + "");        Resources r = this.getResources();        int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, r.getDisplayMetrics());        GridLayout.LayoutParams params = new GridLayout.LayoutParams();        params.width = px;        button.setLayoutParams(params);        mGridLayout.addView(button, Math.min(1, mGridLayout.getChildCount()));        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mGridLayout.removeView(button);            }        });    }}

如果不用setAnimator()方法重新设置 LayoutTransition 的动画,这里就默认所有动画框架都启用。因为要让大家更直观的看到添加View的动画,所以把新加进来的 Button 在GridLayout中的索引更改为1,这样就很清晰的看到其它 View 的变化。

2、修改动画

接下来我再动态的改变 LayoutTransition 的动画框架的启用,让大家与不用 LayoutTransition 是对比,也加深大家对那四种动画的理解。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.ht.animator.LayoutTransitionActivity">    <Button        android:onClick="addView"        android:text="add"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:id="@+id/button" />    <CheckBox        android:id="@+id/id_appear"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:checked="true"        android:text="APPEARING" />    <CheckBox        android:id="@+id/id_change_appear"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:checked="true"        android:text="CHANGE_APPEARING" />    <CheckBox        android:id="@+id/id_disappear"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:checked="true"        android:text="DISAPPEARING" />    <CheckBox        android:id="@+id/id_change_disappear"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:checked="true"        android:text="CHANGE_DISAPPEARING " /></LinearLayout>

我再布局文件中添加了四个 CheckBox,用来四种动画框架的启用,然后就要在Java代码里为这四个控件初始化,设置监听事件,接口的引用就不提啦。

private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear;
mAppear = (CheckBox) findViewById(R.id.id_appear);mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear);mDisAppear = (CheckBox) findViewById(R.id.id_disappear);mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear);mAppear.setOnCheckedChangeListener(this);mChangeAppear.setOnCheckedChangeListener(this);mDisAppear.setOnCheckedChangeListener(this);mChangeDisAppear.setOnCheckedChangeListener(this);
@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {    mTransition = new LayoutTransition();    mTransition.setAnimator(        LayoutTransition.APPEARING,        (mAppear.isChecked() ? mTransition         .getAnimator(LayoutTransition.APPEARING) : null));    mTransition    .setAnimator(        LayoutTransition.CHANGE_APPEARING,        (mChangeAppear.isChecked() ? mTransition         .getAnimator(LayoutTransition.CHANGE_APPEARING)         : null));    mTransition.setAnimator(        LayoutTransition.DISAPPEARING,        (mDisAppear.isChecked() ? mTransition         .getAnimator(LayoutTransition.DISAPPEARING) : null));    mTransition.setAnimator(        LayoutTransition.CHANGE_DISAPPEARING,        (mChangeDisAppear.isChecked() ? mTransition         .getAnimator(LayoutTransition.CHANGE_DISAPPEARING)         : null));    mGridLayout.setLayoutTransition(mTransition);}

这里用了 LayoutTransition 的两个方法:

void setAnimator(int transitionType, Animator animator)Animator getAnimator(int transitionType)

setAnimator 显然是更改对应类型的动画啦,这里如果是选中状态,则保持对应动画类型的默认动画,否则就设置为空,效果就是与没设置 LayoutTransition 一样啦,当然只是设置为空的那一个动画类型而已。

可以很清楚的看到,当取消 APPEARING 的选中,则添加的 Button 不会出现淡入的动画,而其它Button是不受影响的。其它选择框也是如此的效果。

3、自定义动画

既然可以把动画设置为空,当然也可以自定义动画啦,设置时间等ValueAnimator 和 ObjectAnimator的方法也可以实现。

mTransition.setAnimator(LayoutTransition.APPEARING, (mAppear                  .isChecked() ? ObjectAnimator.ofFloat(this, "scaleX", 0, 1)                  : null));  

这里就用我们的放大效果的动画替换了系统默认的LayoutTransition.APPEARING。

结束语:本文仅用来学习记录,参考查阅。

3 0