Android SDK提供了linear_interpolator、accelerate_interpolator、decelerate_interpolator、accelerator_decelerate_interpolator,其实还有一个cycle_interpolator,可以将它作为振动动画渲染器。由于其未在系统中定义,因此需要自己编写cycle_interpolator.xml文件,内容如下:
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="18" />
其中android:cycles表示振动因子,该属性值越大,振动得越剧烈。
还有一个动画文件shake.xml,内容如下
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:fromXDelta="0" android:interpolator="@anim/cycle_interpolator" android:toXDelta="10" />
如果想在Java代码中实现振动效果,需要创建CycleInterpolator对象,CycleInterpolator类构造方法的定义如下:
public CycleInterpolator(float cycles)
通过该构造方法可以设置振动因子。
public class Main extends Activity implements OnClickListener { @Override public void onClick(View view) { Animation animation = AnimationUtils.loadAnimation(this, R.anim.shake); EditText editText = (EditText)findViewById(R.id.edittext); editText.startAnimation(animation); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } }
自定义的动画渲染器:
实际上,我们也可以自己定义动画渲染器。要实现动画渲染器,需要实现Interpolator接口。示例实现了一个可以来回弹跳的动画渲染器。
渲染器的代码如下:
public class MyInterceptor implements Interpolator { @Override public float getInterpolation(float input) { if (input <= 0.5) return input * input; else return (1 - input) * (1 - input) ; } }
在Interpolator接口中只有一个getInterpolation方法。该方法有一个float类型的参数,取值范围在0.0~1.0之间,表示动画的进度。如果该值为0.0。表示动画刚开始。如果参数值为1.0,表示动画已结束。如果getInterpolation方法的返回值小于1.0,则表示动画对象还没有到达目标点,越接近1.0。目标对象离目标点越近,当返回值为1.0的时候,正好到达目标点。如果getInterpolation方法的返回值大于1.0,表示动画对象超过了目标点。例如在等移动补间动画中,getInterpolation方法的返回值是2.0,表示动画对象超过了目标点,并且距目标点的距离等于目标点到起点的距离。
下面是translate.xml文件的内容:
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="5000" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="1550" />
装载和开始动画
public class Main extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageView imageView = (ImageView)findViewById(R.id.imageview); Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate); animation.setInterpolator(new MyInterceptor());//装在自定义动画渲染器 animation.setRepeatCount(Animation.INFINITE); imageView.startAnimation(animation); } }
以动画方式切换View的组件ViewFlipper
ViewFlipper可以实现不同View之间的切换。本示例,包含了三个XML布局文件,layout1.xml、layout2.xml、layout3.xml来定义三个View,每一个View都包含一个ImageView组件,当触摸第一个ImageView时,会以水平左移的方式切换到底二个ImageView。触摸第二个时,会以淡入淡出的方式切换到第三个ImageView
示例代码如下:
<?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:orientation="vertical" > <ImageView android:id="@+id/imageview1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/image1" /> </LinearLayout>
public class Main extends Activity implements OnTouchListener { private ViewFlipper viewFlipper; private Animation translateIn; private Animation translateOut; private Animation alphaIn; private Animation alphaOut; @Override public boolean onTouch(View view, MotionEvent event) { switch (view.getId()) { case R.id.imageview1: viewFlipper.setInAnimation(translateIn);//关键代码 viewFlipper.setOutAnimation(translateOut); break; case R.id.imageview2: viewFlipper.setInAnimation(alphaIn);//关键代码 viewFlipper.setOutAnimation(alphaOut); break; } viewFlipper.showNext(); return false; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewFlipper = (ViewFlipper) getLayoutInflater().inflate(R.layout.main, null); View view1 = getLayoutInflater().inflate(R.layout.layout1, null); View view2 = getLayoutInflater().inflate(R.layout.layout2, null); View view3 = getLayoutInflater().inflate(R.layout.layout3, null); viewFlipper.addView(view1); viewFlipper.addView(view2); viewFlipper.addView(view3); setContentView(viewFlipper); translateIn = AnimationUtils.loadAnimation(this, R.anim.translate_in); translateOut = AnimationUtils.loadAnimation(this, R.anim.translate_out); alphaIn = AnimationUtils.loadAnimation(this, R.anim.alpha_in); alphaOut = AnimationUtils.loadAnimation(this, R.anim.alpha_out); ImageView imageView1 = (ImageView) view1.findViewById(R.id.imageview1); ImageView imageView2 = (ImageView) view2.findViewById(R.id.imageview2); imageView1.setOnTouchListener(this); imageView2.setOnTouchListener(this); } }