第七章 Android动画机制与技巧
2018-03-12 21:26
288 查看
Android属性动画
private void objectAnimatorText1() { setContentView(R.layout.activity_main); final Button button = (Button) findViewById(R.id.bt); LinearLayout linearLayout = findViewById(R.id.ll); final TextView textViewFirst = linearLayout.findViewById(R.id.tv_first); button.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override public void onClick(View v) { /** * 操作的属性必须要有set、get方法,不然无法起效 */ ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(button, "translationX", 300); objectAnimator1.start(); /** * 通过插值器,可以定义动画变化速率,类似于物理中的加速度 * * 线性插值器:在持续时间内,单位时间所移动的距离都是一样的 * 加速度插值器:单位时间内所移动的距离越来越快 */ objectAnimator1.setInterpolator(); objectAnimator1.addListener(new AnimatorListenerAdapter() { /** * 大部分我们只关心动画结束事件 */ @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } }); /** * 操作的属性没有set、get方法,通过自定义一个属性类或者包装类,来间接给这个属性增加set、get方法 */ WrapperView wrapperView = new WrapperView(button); ObjectAnimator objectAnimator2 = ObjectAnimator.ofInt(wrapperView, "width", 300); objectAnimator2.start(); /** * 类似视图动画中的AnimationSet */ PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", 300f); PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f); PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f); ObjectAnimator.ofPropertyValuesHolder(button, holder1, holder2, holder3).setDuration(1000).start(); /** * ValueAnimator本身不提供任何动画效果,更像是一个数值发生器, */ ValueAnimator animator = ValueAnimator.ofInt(0, 400); animator.setTarget(button); animator.setDuration(1000).start(); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { /** * 可以使用该数值做想做的事 */ int animatedValue = (int) animation.getAnimatedValue(); Log.i(TAG, "onAnimationUpdate: "+animatedValue); /** * 计时器动画 */ textViewFirst.setText(String.valueOf(animatedValue)); } }); /** * Android3.0之后,Geogle给View增加了这样一种简易的方式驱动属性动画 */ button.animate().alpha(0).y(300).setDuration(3000) .withStartAction(new Runnable() { @Override public void run() { } }).withEndAction(new Runnable() { @Override public void run() { } }).start(); /** * 自定义动画 */ MyAnimation myAnimation = new MyAnimation(); myAnimation.setDuration(1000); button.startAnimation(myAnimation); } }); /** * 布局动画 */ LinearLayout linearLayout = findViewById(R.id.ll); ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1); scaleAnimation.setDuration(2000); /** * 第一个参数是需要作用的动画,第二个参数是每个子view显示的delay时间 * 当viewGroup添加view的时候,通过LayoutAnimationController定义一个子view的过渡效果 */ LayoutAnimationController controller = new LayoutAnimationController(scaleAnimation, 0.5f); /** * delay时间不为0的时候可以设置这个 * * 子view出现的顺序: * ORDER_NORMAL: 顺序 * ORDER_RANDOM: 随机 * ORDER_REVERSE: 反序 */ controller.setOrder(LayoutAnimationController.ORDER_REVERSE); linearLayout.setLayoutAnimation(controller); } private static class WrapperView{ private View mTarget; public WrapperView(View target){ mTarget = target; } public void setWidth(int width){ mTarget.getLayoutParams().width = width; mTarget.requestLayout(); } public int getWidth(){ return mTarget.getLayoutParams().width; } }
自定义动画
/** * 自定义动画 */ public class MyAnimation extends Animation { private Camera mCamera; private int mCenterWidth; private int mCenterHeight; private int mRotateY = 45; public MyAnimation(){ mCamera = new Camera(); } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); setDuration(2000); /** * 动画结束后保留状态 */ setFillAfter(true); b576 setInterpolator(new BounceInterpolator()); mCenterWidth = width/2; mCenterHeight = height/2; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); /** * 获得当前的矩阵对象 */ Matrix matrix = t.getMatrix(); mCamera.save(); mCamera.rotateY(mRotateY*interpolatedTime); /** * 将旋转变换作用到Matrix */ mCamera.getMatrix(matrix); mCamera.restore(); /** * 通过pre方法设置矩阵作用前的偏移量来改变旋转中心 */ matrix.preTranslate(mCenterWidth, mCenterHeight); matrix.postTranslate(-mCenterWidth, mCenterHeight); } }
下拉展开动画
实现类似商城购物车里的删除、收藏按钮。private void dropAnimatorText() { setContentView(R.layout.drop); LinearLayout ll_click = findViewById(R.id.ll_click); final LinearLayout hidden_view = findViewById(R.id.hidden_view); // 获取像素密度 mDensity = getResources().getDisplayMetrics().density; /** * 获取布局的高度,40dp是布局的高度,这里转化为了像素值 * * 因为view还没有测量完毕,所以获取不到高 */ Log.i(TAG, "dropAnimatorText: "+hidden_view.getMeasuredHeight()); mViewHeight = (int) (mDensity * 40 + 0.5); ll_click.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (hidden_view.getVisibility() == View.GONE){ animataOpen(hidden_view); }else { animataClose(hidden_view); } } }); } private void animataClose(final LinearLayout hidden_view) { int height = hidden_view.getHeight(); ValueAnimator animator = createDropAnimator(hidden_view, height, 0); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { hidden_view.setVisibility(View.GONE); } }); animator.start(); } private void animataOpen(View hidden_view) { hidden_view.setVisibility(View.VISIBLE); ValueAnimator animator = createDropAnimator(hidden_view, 0, mViewHeight); animator.start(); } private ValueAnimator createDropAnimator(final View hidden_view, int start, int end) { ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int animatedValue = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams layoutParams = hidden_view.getLayoutParams(); layoutParams.height = animatedValue; hidden_view.setLayoutParams(layoutParams); } }); return animator; }
相关文章推荐
- Android群英转读书笔记第七章(Android动画机制与使用技巧)
- 《Android群英传》读书笔记(8)第七章:Android动画机制与使用技巧
- Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
- Android群英传学习——第七章、Android动画机制与使用技巧
- Android群英传知识点回顾——第七章:Android动画机制与使用技巧
- Android群英传笔记——第七章:Android动画机制和使用技巧
- Android群英传笔记——第七章:Android动画机制和使用技巧
- 第七章Android动画机制与使用技巧(Android群英传)
- Android动画机制与使用技巧(三)——动画补充知识
- Android群英传之Android动画机制与使用技巧
- Android动画机制与使用技巧(三)Android动画特效
- Android动画机制与使用技巧(二)布局动画、插值器、自定义动画
- Android 动画机制与使用技巧
- Android 动画机制与使用技巧
- Android进阶-Android动画机制与使用技巧
- Android动画机制与使用技巧(二)——属性动画分析
- Android动画机制与使用技巧(四)——Android动画特效
- Android动画机制与使用技巧(一)属性动画分析
- Android动画机制与使用技巧
- Android动画机制与使用技巧(四)Android 5.X SVG矢量动画机制