Android群英转读书笔记第七章(Android动画机制与使用技巧)
2016-06-01 14:36
573 查看
动画的分类
动画分为视图动画(View)和属性动画(Property),而视图动画又分为Tween动画和Frame动画,属性动画又分为ValueAnimator和ObjectAnimator.属性动画简介
从Android3.0开始出现,真实改变View的属性,可以响应事件使用ObjectAnimator时,对象的属性必须有get和set方法,因为内部会通过反射来调用属性的set方法,如果一个属性没有get和set方法,可以通过下面两种方式来解决。
1.自定义一个属性类或者包装类
2.使用ValueAnimator
public class WrapperView { private View mTargetView; public WrapperView(View targetView){ mTargetView = targetView; } public int getWidth(){ return mTargetView.getLayoutParams().width; } public void setWidth(int width){ mTargetView.getLayoutParams().width = width; mTargetView.requestLayout(); } }
public class MainActivity extends AppCompatActivity { private WrapperView wrapperView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.button); wrapperView = new WrapperView(btn); } public void click(View view){ ObjectAnimator.ofInt(wrapperView,"width",0,500).setDuration(5000).start(); } }
在属性动画中,使用PropertyValueHolder可以使多个动画共同作用,用法类似于AnimationSet的使用。
ValueAnimator
本身不提供任何动画效果,更像一个数值发生器,用来产生一定规律的数字,从而让调用者控制动画的实现过程。用法如下
//创建对象 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1); //设置要添加动画的view valueAnimator.setTarget(btn); valueAnimator.setDuration(4000); //启动动画 valueAnimator.start(); //添加监听 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //不断获取动画过程中的值 float animatedValue = (float) animation.getAnimatedValue(); btn.setAlpha(animatedValue); } });
AnimatorSet也可以对一个属性进行多个动画,还能控制顺序,比前面的PropertyValueHolder更强大。
View的animate方法
在API16之后,提供了animate方法直接驱动属性动画
btn.animate().alpha(0).y(200).setDuration(2000) .withStartAction(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "开始", Toast.LENGTH_SHORT).show(); } }).withEndAction(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "结束", Toast.LENGTH_SHORT).show(); } }); }
布局动画
布局动画是指作用在ViewGroup上,给ViewGroup添加View时增加一个动画效果。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll = (LinearLayout) findViewById(R.id.ll); TranslateAnimation animation = new TranslateAnimation(720,0,0,0); animation.setDuration(2000); LayoutAnimationController controller = new LayoutAnimationController(animation,0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); ll.setLayoutAnimation(controller); addView(); } public void addView(){ for (int i = 0; i < 10; i++) { TextView textView = new TextView(this); textView.setText("文字"+i); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ll.addView(textView,params); } }
自定义动画
步骤:
1.重写initialize方法做初始化动作
2.重写applyTransformation方法
public class RotateAnim extends Animation { private int mCenterWidth; private int mCenterHeight; private Camera camera = new Camera(); private float mRotateY = 0.0f; @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); setDuration(2000); setFillAfter(true); setInterpolator(new BounceInterpolator()); mCenterWidth = width/2; mCenterHeight = height/2; } public void setRotateY(float rotateY){ mRotateY = rotateY; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); Matrix matrix = t.getMatrix(); camera.save(); camera.rotateY(mRotateY*interpolatedTime); camera.getMatrix(matrix); camera.restore(); //设置旋转中心, matrix.preTranslate(mCenterWidth/2,mCenterHeight); matrix.postTranslate(-mCenterWidth/2,-mCenterHeight); } }
Android 5.X SVG 矢量动画机制
SVG是可伸缩矢量图形,使用XML格式定义图形,图像在放大或者改变尺寸的情况下图像质量不会有损失。
Android中使用SVG需要使用下面两个API
VectorDrawable:创建基于XML的SVG图形
AnimatedVerctorDrawable:实现动画效果,比喻为一个胶水,连接静态的VectorDrawable和动态的objectAnimator
动画特效
public class MainActivity extends AppCompatActivity { private LinearLayout hiddenView; private LinearLayout ll; private boolean flag = false; private float density; private int hiddenViewHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); density = getResources().getDisplayMetrics().density; hiddenViewHeight = (int) (density*40+0.5f); ll = (LinearLayout) findViewById(R.id.ll); hiddenView = (LinearLayout) findViewById(R.id.hiddenView); ll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(hiddenView.getVisibility() == View.GONE){ hiddenView.setVisibility(View.VISIBLE); ValueAnimator animator = createAnimation(hiddenView, 0, hiddenViewHeight); animator.start(); }else{ int oriHeight = hiddenView.getHeight(); ValueAnimator animator = createAnimation(hiddenView, oriHeight, 0); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { hiddenView.setVisibility(View.GONE); } }); animator.start(); } } }); } public ValueAnimator createAnimation(final View view, int start, int end){ ValueAnimator animator = ValueAnimator.ofInt(start,end); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); params.height = (int) animation.getAnimatedValue(); view.setLayoutParams(params); } }); flag = true; return animator; } }
相关文章推荐
- Android-----fragment-----跳转总结
- Android绘图机制与处理技巧(五)——View的孪生兄弟SurfaceView
- Android开发笔记(一百零三)地图与定位SDK
- Android Studio 2.1.1 中使用直接JNI与间接编译JNI
- android 分页加载
- android:ExpandableListView(可扩展的ListView)使用详解;
- Android开发之内存管理
- Android自定义控件+popuwindow下拉菜单的实现仿58下拉菜单
- android中三种动画
- android-----自定义View实现系列(一)
- android-----Volley框架源码分析
- AndroidKK4.4 Power key电量屏幕时button light先亮LCD后亮的卡顿有关问题分析
- Bootchart分析Android启动时间
- 开源中国(oschina)Android客户端主页返回按钮效果实现
- Android 有关于* daemon not running.starting it now on port 5037 *ADB
- Android 有关于* daemon not running.starting it now on port 5037 *ADB
- Android自定义View4——统计图View
- Android SDK Manager不显示更新问题的解决
- Android6.0权限操作
- 【Android】当xutils3遇到umeng统计