作者微信 bishe2022

代码功能演示视频在页面下方,请先观看;如需定制开发,联系页面右侧客服
Android Layout 布局动画的介绍

Custom Tab

LayoutTransition 类介绍

       我们先来认识一个重要的类--LayoutTransition,该类是Android API提供的用于动画显示ViewGroup中的Layout的帮助类,我们可以使用该类设置动画并绑定目标Layout。那一般在什么情况下为Layout设置动画效果呢?比方说,如果我们需要对一个Layout实现动态地添加或删除子View对象,那么我们可以分别为需添加或删除的View对象在移动到新的位置的过程添加动画形式。一般地,Layout中的View对象有四种动画变化的形式,如下:

      APPEARING —— 元素在容器中显现时需要动画显示。
      CHANGE_APPEARING —— 由于容器中要显现一个新的元素,其它元素的变化需要动画显示。
      DISAPPEARING —— 元素在容器中消失时需要动画显示。
      CHANGE_DISAPPEARING —— 由于容器中某个元素要消失,其它元素的变化需要动画显示。

其实这四种动画形式也很好理解,举个例子,我们有一个GridLayout中有多个Button对象,如果需要删除其中一个Button对象的话,该Button对象可以设置动画(即DISAPPEARING 动画形式),Layout中的其它Button对象此时移动到新的位置的过程中也可以设置相关的动画(即CHANGE_DISAPPEARING 动画形式),如图下:

qqqqqqqqqq.jpg

而当需要为Layout添加一个新的Button对象时,此时我们可以为这个 新添加的Button对象设置动画(即APPEARING 动画形式),Layout中的其它Button对象此时移动到新的位置过程也可以设置相关的动画(即CHANGE_APPEARING动画形式 ),如图下:

wwwww.jpg

那基本了解了这四种动画形式后,我们又应该如何使用呢?LayoutTransition类中有一个setAnimator(int transitionType, Animator animator)用于添加动画以及设置动画形式类型,在开发当中,我们只需要确定好需要在不同的动画类型中显示什么动画,然后创建并设置好相关的动画对象,最后使用该方法将两者进行绑定就行。那废话不多说,下面我们通过一个例子来学习一下如何为Layout添加动画。代码实例在文章末尾提供下载,

下面是LayoutAnimatorFragment主界面及和主要功能代码,如下:

/** 
 * @author AndroidLeaf 
 *ViewGroup中Layout的动画实现 
 *主要知识点: 
 *调用 LayoutTransition 对象的 setAnimator() 方法来定义下列动画方式,调用参数是 Animator 
 *对象和以下 LayoutTransition 常量: 
 *  (1)APPEARING —— 元素在容器中显现时需要动画显示。 
 *  (2)CHANGE_APPEARING —— 由于容器中要显现一个新的元素,其它元素的变化需要动画显示。 
 *  (3)DISAPPEARING —— 元素在容器中消失时需要动画显示。 
 *  (4)CHANGE_DISAPPEARING —— 由于容器中某个元素要消失,其它元素的变化需要动画显示。 
 */  
public class LayoutAnimatorFragment extends Fragment implements OnClickListener{  
  
    private Button mButtonAdd;  
    private Button mButtonReset;  
    private GridLayout mGridLayout;  
    private int buttonNumbers = 1;  
      
    private LayoutTransition mLayoutTransition;  
      
    @Override  
    public void onActivityCreated(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onActivityCreated(savedInstanceState);  
          
    }  
  
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        View rootView = inflater.inflate(R.layout.fragment_layoutanimator, container, false);  
        initViews(rootView);  
        return rootView;  
    }  
      
    public void initViews(View rootView){  
          
        mButtonAdd = (Button)rootView.findViewById(R.id.layout_animator_addbutton);  
        mButtonAdd.setOnClickListener(this);  
        mButtonReset = (Button)rootView.findViewById(R.id.layout_animator_resetbutton);  
        mButtonReset.setOnClickListener(this);  
        mGridLayout = (GridLayout)rootView.findViewById(R.id.layout_animator_gridview);  
        mLayoutTransition = new LayoutTransition();  
        //为GridLayout设置mLayoutTransition对象  
        mGridLayout.setLayoutTransition(mLayoutTransition);  
        mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, 30);  
        mLayoutTransition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);  
        //设置每个动画持续的时间  
        mLayoutTransition.setDuration(300);  
        //初始化自定义的动画效果  
        customLayoutTransition();  
    }  
  
    @Override  
    public void onPause() {  
        // TODO Auto-generated method stub  
        super.onPause();  
          
    }  
  
    @Override  
    public void onClick(View v) {  
        // TODO Auto-generated method stub  
        switch (v.getId()) {  
        case R.id.layout_animator_addbutton:  
            addButton();  
            break;  
        case R.id.layout_animator_resetbutton:  
            resetButton();  
            break;  
        default:  
            break;  
        }  
    }  
      
    /** 
     * 增加Button 
     */  
    public void addButton(){  
        Button mButton = new Button(getActivity());  
        LinearLayout.LayoutParams mLayoutParams = new LinearLayout.LayoutParams(50, 50);  
        mButton.setLayoutParams(mLayoutParams);  
        mButton.setText(String.valueOf(buttonNumbers++));  
        mButton.setTextColor(Color.rgb(0, 0, 0));  
        if(buttonNumbers % 2 == 1){  
            mButton.setBackgroundColor(Color.rgb(45, 118, 87));  
        }else{  
            mButton.setBackgroundColor(Color.rgb(225, 24, 0));  
        }  
        mButton.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                mGridLayout.removeView(v);  
            }  
        });  
          
        mGridLayout.addView(mButton, Math.min(1, mGridLayout.getChildCount()));  
    }  
      
    /** 
     * 删除所有的Button,重置GridLayout 
     */  
    public void resetButton(){  
        mGridLayout.removeAllViews();  
        buttonNumbers = 1;  
    }  
      
    public void customLayoutTransition(){  
          
        /** 
         * Add Button 
         * LayoutTransition.APPEARING 
         * 增加一个Button时,设置该Button的动画效果 
         */  
        ObjectAnimator mAnimatorAppearing = ObjectAnimator.ofFloat(null, "rotationY", 90.0f,0.0f)  
                .setDuration(mLayoutTransition.getDuration(LayoutTransition.APPEARING));  
        //为LayoutTransition设置动画及动画类型  
        mLayoutTransition.setAnimator(LayoutTransition.APPEARING, mAnimatorAppearing);  
        mAnimatorAppearing.addListener(new AnimatorListenerAdapter() {  
            @Override  
            public void onAnimationEnd(Animator animation) {  
                // TODO Auto-generated method stub  
                super.onAnimationEnd(animation);  
                 View view = (View) ((ObjectAnimator) animation).getTarget();  
                 view.setRotationY(0.0f);  
            }  
        });  
          
        /** 
         * Add Button 
         * LayoutTransition.CHANGE_APPEARING 
         * 当增加一个Button时,设置其他Button的动画效果 
         */  
          
        PropertyValuesHolder pvhLeft =  
                    PropertyValuesHolder.ofInt("left", 0, 1);  
        PropertyValuesHolder pvhTop =  
                PropertyValuesHolder.ofInt("top", 0, 1);  
        PropertyValuesHolder pvhRight =  
                PropertyValuesHolder.ofInt("right", 0, 1);  
        PropertyValuesHolder pvhBottom =  
                PropertyValuesHolder.ofInt("bottom", 0, 1);  
          
        PropertyValuesHolder mHolderScaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f,0.0f,1.0f);  
        PropertyValuesHolder mHolderScaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f,0.0f,1.0f);  
        ObjectAnimator mObjectAnimatorChangeAppearing = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft,  
                pvhTop,pvhRight,pvhBottom,mHolderScaleX,mHolderScaleY).setDuration(mLayoutTransition  
                        .getDuration(LayoutTransition.CHANGE_APPEARING));  
        mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mObjectAnimatorChangeAppearing);  
        mObjectAnimatorChangeAppearing.addListener(new AnimatorListenerAdapter() {  
            @Override  
            public void onAnimationEnd(Animator animation) {  
                // TODO Auto-generated method stub  
                super.onAnimationEnd(animation);  
                 View view = (View) ((ObjectAnimator) animation).getTarget();  
                 view.setScaleX(1f);  
                 view.setScaleY(1f);  
            }  
        });  
          
        /** 
         * Delete Button 
         * LayoutTransition.DISAPPEARING 
         * 当删除一个Button时,设置该Button的动画效果 
         */  
        ObjectAnimator mObjectAnimatorDisAppearing = ObjectAnimator.ofFloat(null, "rotationX", 0.0f,90.0f)  
                .setDuration(mLayoutTransition.getDuration(LayoutTransition.DISAPPEARING));  
        mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mObjectAnimatorDisAppearing);  
        mObjectAnimatorDisAppearing.addListener(new AnimatorListenerAdapter() {  
            @Override  
            public void onAnimationEnd(Animator animation) {  
                // TODO Auto-generated method stub  
                super.onAnimationEnd(animation);  
                 View view = (View) ((ObjectAnimator) animation).getTarget();  
                 view.setRotationX(0.0f);  
            }  
        });  
          
        /** 
         * Delete Button 
         * LayoutTransition.CHANGE_DISAPPEARING 
         * 当删除一个Button时,设置其它Button的动画效果 
         */  
        //Keyframe 对象中包含了一个时间/属性值的键值对,用于定义某个时刻的动画状态。  
        Keyframe mKeyframeStart = Keyframe.ofFloat(0.0f, 0.0f);  
        Keyframe mKeyframeMiddle = Keyframe.ofFloat(0.5f, 180.0f);  
        Keyframe mKeyframeEndBefore = Keyframe.ofFloat(0.999f, 360.0f);  
        Keyframe mKeyframeEnd = Keyframe.ofFloat(1.0f, 0.0f);  
          
        PropertyValuesHolder mPropertyValuesHolder = PropertyValuesHolder.ofKeyframe("rotation",   
                mKeyframeStart,mKeyframeMiddle,mKeyframeEndBefore,mKeyframeEnd);  
        ObjectAnimator mObjectAnimatorChangeDisAppearing = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft,pvhTop,pvhRight,pvhBottom,mPropertyValuesHolder)  
                .setDuration(mLayoutTransition.getDuration(LayoutTransition.CHANGE_DISAPPEARING));  
        mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mObjectAnimatorChangeDisAppearing);  
        mObjectAnimatorChangeDisAppearing.addListener(new AnimatorListenerAdapter() {  
            @Override  
            public void onAnimationEnd(Animator animation) {  
                // TODO Auto-generated method stub  
                super.onAnimationEnd(animation);  
                 View view = (View) ((ObjectAnimator) animation).getTarget();  
                  view.setRotation(0.0f);  
            }  
        });  
    }  
}

LayoutAnimatorFragment的界面布局fragment_layoutanimator.xml代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:background="@color/view_animation_background"  
    android:orientation="vertical"  
     >  
    <LinearLayout   
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:orientation="horizontal"  
        >  
        <Button   
            android:layout_width="0dp"  
            android:layout_weight="1"  
            android:layout_height="wrap_content"  
            android:text="Add Button"  
            android:id="@+id/layout_animator_addbutton"  
            />  
        <Button  
            android:layout_width="0dp"  
            android:layout_weight="1"  
            android:layout_height="wrap_content"  
            android:text="Reset Button"  
            android:id="@+id/layout_animator_resetbutton"   
            />  
    </LinearLayout>  
   <ScrollView   
       android:layout_width="match_parent"  
       android:layout_height="match_parent"  
       >  
       <GridLayout  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:columnCount="5"  
        android:animateLayoutChanges="true"   
        android:id="@+id/layout_animator_gridview"  
        />  
   </ScrollView>  
      
</LinearLayout>

布局界面比较简单,唯一要注意的是GridLayout布局中的android:animateLayoutChanges属性,该属性的值为true或false,true代表当前Layout的布局发生改变时使用动画效果,false则不使用。

最后我们运行程序,看一下运行及操作效果图:

aaaa.jpg

小伙伴们,有没感觉上面的动画效果比较炫,哈哈,想要实现的伙伴们赶紧动手吧!

转载自:http://blog.csdn.net/wangjia55/article/details/42743305

Home