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>
<?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; } }
这边是主要的程序,也是主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; }
上面还使用一个对象TimeInterplator,这个属相定义了属性值变化的范围,如线性均匀变化,开始慢然后快等等。timeInterplator是propertyAnimation中使用,在这边列举一些简单的实现对象。
后面再把这三种动画对象的区别讲解下吧。
相关知识参考:
http://www.open-open.com/lib/view/open1329994048671.html
http://android.amberfog.com/