第一次写博客, 不足之处望多多包含本小弟弟.
之所以开始学博客,源于看过一BAT大神写的一篇文章有感,从来不用脑机, 用笔记, 不得不承认这是个事实, 所以想想也挺对的.本人不算聪明,希望勤能补拙了.
为什么写动画?
相信很多刚开始接触工作的同学也有感触, 动画这种东西看起来酷炫, 自己写就难了, 最后还要搞得怀疑下 自己到底是技术问题还是审美问题?总之,踩的坑相信也不少.本宝宝也是受害人之一,不废话,直接进入正题.
首先,Android中动画大概分为三种: 补间动画,属性动画,帧动画. 后者用的场景非常少. 使用最多的是前面两者, 其中属性动画 在官方API中只支持到API 14 也就是Android 4.0. 当然,有大神已经给出了兼容API14以下的兼容包,用法几乎一致. 使用最多的是前面两者, 其中属性动画 在官方API中只支持到API 14 也就是Android 4.0. 当然,有大神已经给出了兼容API14以下的兼容包,用法几乎一致.《NineOldAndroids属性动画》。
那么,在开发中,如果要重新设置某一个view的高,一般的做法是
ViewGroup.LayoutParams params = content.getLayoutParams(); params.height=value; content.setLayoutParams(params);
实现重置content的高度, 但是,在真实机子上效果并不是那么好,感觉变幻很生硬有木有?那么这里就可以使用属性动画解决这个问题。
为什么不用补间动画? 如果使用补间动画,也可以达到伸展效果。这时候会出现2个问题:
第一,补间动画在视觉上是达到了你想要的动画效果, 但是在执行的过程中程序内部没有调用onmeasure()和 onlayout(),它只调用了ondraw(),也就是说,这时候你看到的并非是你看到的,它的属性没有改变. view的top,left,right.bottom 4个属性并没有改变。
第二,这个问题的出现,其实也是因为第一个原因, 在做动画的view周围的所有view,其位置并没有跟着动画view的位置或形状的改变而改变,这是个大问题,所以排除使用补间动画,改用属性动画。
好的,BB够了,请品尝代码。。。
主界面是activity_main.xml 是一个LinearLayout 包裹3个View ,标题View,伸展内容View,尾部View。
<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" tools:context="com.demotest.testdemo.MainActivity"> <RelativeLayout android:id="@+id/toggle" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center_vertical" android:background="#cccccc" android:text="标题"/> <ImageView android:id="@+id/arrow" android:layout_width="20dp" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_height="20dp" android:src="@drawable/down_arrow"/> </RelativeLayout> <LinearLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="#666666" android:textColor="#ffffff" android:text="Hello World!" android:orientation="horizontal"/> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center_vertical" android:background="#ff0000" android:textColor="#ffffff" android:text="底部内容"/> </LinearLayout>
</pre><pre>在MainActivity的onCreate方法中,初始化view,初始化动画content的初始状态。 点击标题,content响应:
private void toggleContent(boolean animation) { content.measure(0, 0); //测量宽高 int measuredHeight = content.getMeasuredHeight(); if (isOpen) { //1.内容关闭 if (animation) { //从打开到关闭做--收缩动画 int start = measuredHeight; int end = 0; ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.setDuration(400); animator.addUpdateListener(animationListener); animator.start(); //2.标志旋转属性动画 ObjectAnimator.ofFloat(arrow, "rotation", -180, 0).setDuration(400).start(); } else { //无动画效果 ViewGroup.LayoutParams params = content.getLayoutParams(); params.height = 0; content.setLayoutParams(params); arrow.setRotation(0); } } else { //1.内容打开 if (animation) { //从关闭到打开做--伸展动画 int start = 0; int end = measuredHeight; ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.setDuration(400); animator.addUpdateListener(animationListener); animator.start(); //2.标志旋转属性动画 ObjectAnimator.ofFloat(arrow, "rotation", 0, 180).setDuration(400).start(); } else { //无动画效果 ViewGroup.LayoutParams params = content.getLayoutParams(); params.height = measuredHeight; content.setLayoutParams(params); arrow.setRotation(180); } } isOpen = !isOpen; }注册动画过程监听器,不停的设置LayoutParams的height属性。实现伸展效果。
private ValueAnimator.AnimatorUpdateListener animationListener = new android.animation.ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams params = content.getLayoutParams(); params.height = value; content.setLayoutParams(params); } };
看效果: