Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android布局动画--LayoutTransition

$
0
0

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);
@Override
public 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。

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

作者:HardWorkingAnt 发表于2017/5/12 11:23:12 原文链接
阅读:31 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles