Android动画实例
一、弹出菜单
1.1 菜单关闭与打开的组合动画
AnimatorSet set = new AnimatorSet();
set.setDuration(500);
set.setInterpolator(new BounceInterpolator());
set.playTogether(a0, a1, a2, a3, a4);
set.start();
1.2 打开与关闭的动画
ObjectAnimator a1 = ObjectAnimator.ofFloat(mImageViews.get(1), "translationY", 200f);
ObjectAnimator a1 = ObjectAnimator.ofFloat(mImageViews.get(1), "translationY", 200f, 0f);
1.3 运行效果
1.4 源码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_b" android:src="@mipmap/b" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_c" android:src="@mipmap/c" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_d" android:src="@mipmap/d" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_e" android:src="@mipmap/e" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView_a" android:src="@mipmap/a" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
public class MenuTest extends Activity implements View.OnClickListener { private int[] mRes = {R.id.imageView_a, R.id.imageView_b, R.id.imageView_c, R.id.imageView_d, R.id.imageView_e}; private List<ImageView> mImageViews = new ArrayList<>(); private boolean mFlag = true; private AnimatorSet startset; private AnimatorSet set; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.menu_layout); for(int i=0;i<mRes.length;i++){ ImageView imageView = (ImageView) findViewById(mRes[i]); imageView.setOnClickListener(this); mImageViews.add(imageView); } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.imageView_a: /*if(startset != null && startset.isRunning()){ }*/ if(mFlag){ startAnim(); }else{ closeAnim(); } break; } } private void startAnim(){ ObjectAnimator a0 = ObjectAnimator.ofFloat(mImageViews.get(0), "alpha", 1f, 0.5f); ObjectAnimator a1 = ObjectAnimator.ofFloat(mImageViews.get(1), "translationY", 200f); ObjectAnimator a2 = ObjectAnimator.ofFloat(mImageViews.get(2), "translationX", 200f); ObjectAnimator a3 = ObjectAnimator.ofFloat(mImageViews.get(3), "translationY", -200f); ObjectAnimator a4 = ObjectAnimator.ofFloat(mImageViews.get(4), "translationX", -200f); startset = new AnimatorSet(); startset.setDuration(500); startset.setInterpolator(new BounceInterpolator()); startset.playTogether(a0, a1, a2, a3, a4); startset.start(); mFlag = false; } private void closeAnim(){ ObjectAnimator a0 = ObjectAnimator.ofFloat(mImageViews.get(0), "alpha", 0.5f, 1f); ObjectAnimator a1 = ObjectAnimator.ofFloat(mImageViews.get(1), "translationY", 200f, 0f); ObjectAnimator a2 = ObjectAnimator.ofFloat(mImageViews.get(2), "translationX", 200f, 0f); ObjectAnimator a3 = ObjectAnimator.ofFloat(mImageViews.get(3), "translationY", -200f, 0f); ObjectAnimator a4 = ObjectAnimator.ofFloat(mImageViews.get(4), "translationX", -200f, 0f); set = new AnimatorSet(); set.setDuration(500); set.setInterpolator(new BounceInterpolator()); set.playTogether(a0, a1, a2, a3, a4); set.start(); mFlag = true; } }
二、显示隐藏布局
2.1 动画状态监听
利用ValueAnimator的addUpdateListener自己实现动画效果
addListener实现动画结束时监听
2.2 invalidate与requestLayout
两者都能刷新页面,也就是重新执行onDraw(),但invalidate只能强制执行onDraw()实现重绘,如果当前View的布局影响到了兄弟View或者父View时可以使用requestLayout,该方法会对View进行测量、布局、重绘
2.2 运行效果
2.3 源码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:onClick="llClick" android:background="@android:color/holo_blue_bright" android:orientation="horizontal"> <ImageView android:id="@+id/app_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@mipmap/ic_launcher" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:gravity="left" android:text="Click Me" android:textSize="30sp" /> </LinearLayout> <LinearLayout android:id="@+id/hidden_view" android:layout_width="match_parent" android:layout_height="40dp" android:background="@android:color/holo_orange_light" android:gravity="center_vertical" android:orientation="horizontal" android:visibility="gone"> <ImageView android:src="@mipmap/ic_launcher" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:id="@+id/tv_hidden" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:textSize="20sp" android:text="I am hidden" /> </LinearLayout> </LinearLayout>
public class DropTest extends Activity { private LinearLayout mHiddenView; private float mDensity; private int mHeight; private ValueAnimator animator1; private ValueAnimator animator; private boolean flag; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.drop); mHiddenView = (LinearLayout) findViewById(R.id.hidden_view); // 获取布局高度 mDensity = getResources().getDisplayMetrics().density; mHeight = (int) (mDensity * 40 + 0.5f); } public void llClick(View v) { if(animator!=null && animator.isRunning()){ animator.cancel(); } if(animator1!=null && animator1.isRunning()){ animator1.cancel(); } if(flag){ animateClose(mHiddenView); }else{ animateOpen(mHiddenView); } flag = !flag; /*if(mHiddenView.getVisibility() == View.GONE){ animateOpen(mHiddenView); }else { animateClose(mHiddenView); }*/ } private void animateOpen(final View view){ view.setVisibility(View.VISIBLE); animator1 = ValueAnimator.ofInt(0, mHeight); animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); layoutParams.height = value; view.setLayoutParams(layoutParams); view.requestLayout(); } }); animator1.start(); } private void animateClose(final View view){ int height = view.getHeight(); animator = ValueAnimator.ofInt(height, 0); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams params = view.getLayoutParams(); params.height = value; view.setLayoutParams(params); view.requestLayout();// 在不影响兄弟控件或者父控件布局时只需invalidate } }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setVisibility(View.GONE); } }); animator.start(); } }
三、数额显示
3.1 利用ValueAnimator实现数额的显示
ValueAnimator anim = ValueAnimator.ofInt(0, 100);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
text_view.setText(""+animation.getAnimatedValue());
}
});
anim.setDuration(3000);
anim.start();
3.2 效果图
3.3 源码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始" android:textSize="60sp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
public class TimerTest extends Activity implements View.OnClickListener { private TextView text_view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.timer); text_view = (TextView) findViewById(R.id.text_view); text_view.setOnClickListener(this); } @Override public void onClick(View v) { ValueAnimator anim = ValueAnimator.ofInt(0, 100); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { text_view.setText(""+animation.getAnimatedValue()); } }); anim.setDuration(3000); anim.start(); } }