3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:property animation,这三种动画模式在SDK中被称为property animation,view animation,drawable animation。

这篇文章主要使用ObjectAnimator来实现动画的效果。

使用ObjectAnimator这个对象限制性比较多,要满足一定的条件才可以使用,不然动画没有效果。ObjectAnimator继承ValueAnimator,其实就是指定一个对象以及该对象的一个属性,当属性值计算完成自动设置该对象的相关属性,即完成propety Antimation的全部两个操作。

条件为:

1.对象应该有get<属性名> ;set<属性名>方法。

2.ofInt或者ofFloat方法第一个参数是对象名,第二个参数是属性值,后面的参数为可变参数,如果可变参数为1个值,会假定目的值,获取当前值会调用get<属性值>这个方法。

这边用一个简单的例子实现这个动画

首先有3个xml,一个主Activity的main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:id="@+id/l1"    android:baselineAligned="false" >    <FrameLayout        android:id="@+id/fragment1"        android:layout_width="300dp"        android:background="#FF0000"        android:layout_height="fill_parent" />    <FrameLayout        android:id="@+id/fragment2"        android:layout_width="980dp"        android:background="#00FF00"        android:layout_height="fill_parent" /></LinearLayout>
然后定义一个f1.xml和f2.xml作为fragment1和fragment2的布局,然后替换main.xml中的framelayout1和framgelayout2。fragment的操作,大家在网上一搜一大片,怎么使用就不讲了。

f1.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="#30000000"    android:gravity="center"    android:baselineAligned="false" >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="30sp"        android:text="F1" /></LinearLayout>

f2.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:gravity="center"    android:baselineAligned="false" >    <Button        android:id="@+id/btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="go" /></LinearLayout>
fragment1.java

public class Fragment1 extends Fragment {    public static Fragment1 newInstance() {        return new Fragment1();    }    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View root = inflater.inflate(R.layout.f1, container, false);        return root;    }}
fragment2.java

public class Fragment2 extends Fragment {    private WeakReference<FragmentResultListener> mFragmentResultListenerRef;    public interface FragmentResultListener {        public void onBtnClick();    }    public static Fragment2 newInstance(FragmentResultListener listener) {        Fragment2 f = new Fragment2();        f.setFragmentResultListener(listener);        return f;    }    private void setFragmentResultListener(FragmentResultListener listener) {        mFragmentResultListenerRef = new WeakReference<FragmentResultListener>(listener);    }    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View root = inflater.inflate(R.layout.f2, container, false);        root.findViewById(R.id.btn).setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                FragmentResultListener fragmentResultListener = mFragmentResultListenerRef.get();                if (fragmentResultListener != null) {                    fragmentResultListener.onBtnClick();                }            }        });        return root;    }}

这边实现动画的操作需要点击fragment2中的按钮,所以这边使用了回调,先在fragment2中定义个点击的接口,然后再把接口的方法放在按钮的监听事件里面,然后外边调用的时候实现接口的操作,把接口对象传递过来就ok了。

这边是主要的程序,也是主Acitvity的实现逻辑,动画的定义,都在里面。

public class FragmentAnimationTestActivity extends Activity implements Fragment2.FragmentResultListener {    private static final TimeInterpolator sCollapseInterpolator = new DecelerateInterpolator(2.5F);    private View mPanel1;    private View mPanel2;    private View mLayout;    boolean isCollapsed;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mLayout = findViewById(R.id.l1);        mPanel1 = findViewById(R.id.fragment1);        mPanel2 = findViewById(R.id.fragment2);        FragmentTransaction ft = getFragmentManager().beginTransaction();        ft.replace(R.id.fragment1, Fragment1.newInstance(), "f1");        ft.replace(R.id.fragment2, Fragment2.newInstance(this), "f2");        ft.commit();    }    public int getPanelLeft() {        return ((ViewGroup.MarginLayoutParams) mLayout.getLayoutParams()).leftMargin;    }    public void setPanelLeft(int paramInt) {        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mLayout.getLayoutParams();        lp.leftMargin = paramInt;        mLayout.setLayoutParams(lp);    }    public int getPanel2W() {        return ((ViewGroup.MarginLayoutParams) mPanel2.getLayoutParams()).width;    }    public void setPanel2W(int paramInt) {        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mPanel2.getLayoutParams();        lp.width = paramInt;        mPanel2.setLayoutParams(lp);    }    @Override    public void onBtnClick() {        if (isCollapsed) {            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[2];            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofInt("PanelLeft", -300, 0);            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofInt("Panel2W", 1280, 980);            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,                    arrayOfPropertyValuesHolder).setDuration(400);            localObjectAnimator.setInterpolator(sCollapseInterpolator);            localObjectAnimator.start();        } else {            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[2];            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofInt("PanelLeft", 0, -300);            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofInt("Panel2W", 980, 1280);            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,                    arrayOfPropertyValuesHolder).setDuration(400);            localObjectAnimator.setInterpolator(sCollapseInterpolator);            localObjectAnimator.start();        }        isCollapsed = !isCollapsed;    }

上面主要使用了ObjectAnimator动画对象,其中ofInt使用了“panelLef'和”panel2W“这2个属性,这2个属性的set和get方法以及ofInt的使用。条件已经满足可以使用ObjectAnimaor对象。

上面还使用一个对象TimeInterplator,这个属相定义了属性值变化的范围,如线性均匀变化,开始慢然后快等等。timeInterplator是propertyAnimation中使用,在这边列举一些简单的实现对象。

  • AccelerateInterpolator      加速,开始时慢中间加速
  • DecelerateInterpolator       减速,开始时快然后减速
  • AccelerateDecelerateInterolator  先加速后减速,开始结束时慢,中间加速
  • AnticipateInterpolator      反向 ,先向相反方向改变一段再加速播放
  • AnticipateOvershootInterpolator  反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
  • BounceInterpolator       跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
  • CycleIinterpolator        循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
  • LinearInterpolator        线性,线性均匀改变
  • OvershottInterpolator      超越,最后超出目的值然后缓慢改变到目的值
  • TimeInterpolator        一个接口,允许你自定义interpolator,以上几个都是实现了这个接口

    后面再把这三种动画对象的区别讲解下吧。

    相关知识参考:

    http://www.open-open.com/lib/view/open1329994048671.html

    http://android.amberfog.com/

  • 更多相关文章

    1. android中ContactsContract获取联系人的方法
    2. Android(安卓)Material Design :LinearLayoutCompat添加分割线div
    3. Android系统横竖屏切换时候Activity的生命周期
    4. android 3D 游戏实现之综合实例(初步)
    5. Android实现ListView异步加载图片总结
    6. android之Handler的使用,回到主线程更新UI的四种方法
    7. Android知识点总结(十五) Android(安卓)MVP 简易模型
    8. 动态Android编程
    9. 面试题总结(2018.7.26开始,持续更新中)

    随机推荐

    1. 申请 Android MapView 的apiKey流程
    2. Android 视图绑定,找不到类 'ResultProfil
    3. android延迟进入主界面和点击按钮进入主
    4. Android自学笔记(番外篇):全面搭建Linux环境
    5. Android菜单应用(Menu)
    6. Android 如何使一个service 开机启动
    7. Activity切换导致的onCreate重复执行
    8. Android 之 adapter.notifyDataSetChange
    9. Android的contentDescription属性是什么?
    10. android 调用前摄像头进行拍照的方法及完