淘宝客优惠券网站怎么做,wordpress 页面瀑布流,河南平台网站建设价位,房产中介网站建设模板卫星菜单是现在一个非常受欢迎的“控件”#xff0c;很多Android程序员都趋之若鹜#xff0c;预览如下图。传统的卫星菜单是用Animation实现的#xff0c;需要大量的代码#xff0c;而且算法极多#xff0c;一不小心就要通宵Debug。本帖贴出用属性动画Animator来实现卫星菜… 卫星菜单是现在一个非常受欢迎的“控件”很多Android程序员都趋之若鹜预览如下图。传统的卫星菜单是用Animation实现的需要大量的代码而且算法极多一不小心就要通宵Debug。本帖贴出用属性动画Animator来实现卫星菜单。 一、浅析属性动画Animator Animator是Android3.0发布的新功能代码简单效果丰富。属性动画顾名思义只要是可以GET和SET的属性我们都可以用属性动画进行处理。属性动画中常用的属性和方法如下 ValueAnimator //数值发生器可以实现很多很灵活的动画效果
ObjectAnimator //ValueAnimator的子类对ValueAnimator进行了封装让我们可以更轻松的使用属性动画我们通过ObjectAnimator来操纵一个对象产生动画效果
AnimatorListener //对动画的开始、结束、暂停、重复等动作的事件监听需要重写四个方法
AnimatorListenerAdapter //对动画的开始、结束、暂停、重复中的一个动作的事件监听根据选择的动作只需要重写一个方法
AnimatorSet //动画的集合用来设置多个动画之间的关系之前、之后、同时等
PropertyValuesHolder //动画的集合和AnimatorSet类似
TypeEvaluator //值计算器在使用ValueAnimator.ofObject()方法时引入自定义的属性对象
Interpolator //插值器设置动画的特效速度渐变、弹跳等 下面对这几个类做一下简单的介绍 一ObjectAnimatorObjectAnimator是最简单、最常用的属性动画根据文档上的叙述 This subclass of ValueAnimator provides support for animating properties on target objects. 这个ValueAnimator的子类对Object对象的属性提供动画。ObjectAnimator中常用的属性如下 translationX / translationY 水平/垂直平移
rotaionX / rotationY 横向/纵向旋转
scaleX / scaleY 水平/垂直缩放
X / Y 直接到达X/Y坐标
alpha 透明度 我们使用一些方法 ofFloat() 、 ofInt() 、 ofObject() 、 ofPropertyValuesHolder() 等来实现动画调用 start() 方法来启动动画。选择哪个方法主要是属性值的类型决定的。我们先来看看文档中对这几个方法的介绍 target指的是动画的作用对象一般指控件propertyName就是上面说的“translationX”、“alpha”等属性名values是一个不定长数组记录着属性的始末值。唯一不同的是ofPropertyValuesHolder()方法这个方法没有property参数是因为这个参数在PropertyValuesHolder对象中就已经使用下面会介绍PropertyValuesHolder的使用方法。 二AnimatorListener这是一个接口监听属性动画的状态开始/重复/结束/取消Animator及其子类包括ValueAnimator和ObjectAnimator等都可以使用这个接口使用 anim.addListener() 使用这个接口。具体的使用方法如下 animator.addListener(new AnimatorListener() {Override // 动画开始的监听器public void onAnimationStart(Animator animation) { ... }Override // 动画重复的监听器public void onAnimationRepeat(Animator animation) { ... }Override // 动画结束的监听器public void onAnimationEnd(Animator animation) { ... }Override // 动画取消的监听器public void onAnimationCancel(Animator animation) { ... }
}); 三AnimatorListenerAdapter我们在实际开发中往往不会用到AnimatorListener中的全部四个方法所以如果我们使用AnimatorListener不仅浪费系统资源代码看上去也不好看因此我们需要一个适配器Adapter可以让我们根据自己的意愿只实现监听器中的一个或几个方法这就要用到AnimatorListenerAdapter了。AnimatorListenerAdapter的使用方法和AnimatorListener一样都需要使用 anim.addListener() 方法不同的是参数。代码如下 animator.addListener(new AnimatorListenerAdapter() {Overridepublic void onAnimationEnd(Animator animation) { ... }Overridepublic void onAnimationCancel(Animator animation) { ... }
}); 四AnimatorSet先来看文档中的介绍 This class plays a set of Animator objects in the specified order. Animations can be set up to play together, in sequence, or after a specified delay. 这个类支持按顺序播放一系列动画这些动画可以同时播放、按顺序播放也可以在一段时间之后播放主要通过 setStartDelay() 方法实现。下面是文档中对这些方法的介绍 值得说的是play()方法它返回的是一个Builder对象而Builder对象可以通过 with() 、 before() 、 after() 等方法非常方便的控制一个动画与其他Animator动画的先后顺序。例如 AnimatorSet s new AnimatorSet();
s.play(anim1).with(anim2);
s.play(anim2).before(anim3);
s.play(anim4).after(anim3); 五PropertyValuesHolder使用PropertyValuesHolder结合ObjectAnimator或ValueAnimator可以达到AnimatorSet的效果。可以说PropertyValuesHolder就是为了动画集而存在的它不能单独的存在因为它没有target参数因此可以节省系统资源所以只能依靠ObjectAnimator或ValueAnimator存在。一个实例的代码如下 PropertyValuesHolder pvh1 PropertyValuesHolder.ofFloat(translationX, 0F, 200F);
PropertyValuesHolder pvh2 PropertyValuesHolder.ofFloat(translationY, 0F, 200F);
PropertyValuesHolder pvh3 PropertyValuesHolder.ofFloat(rotation, 0F, 360F);
ObjectAnimator.ofPropertyValuesHolder(top, pvh1, pvh2, pvh3).setDuration(2000).start(); 六ValueAnimator是ObjectAnimator的父类但由于不能相应动画也不能设置属性值的是没有target和property两个参数所以不常用。如果我们要监听ValueAnimator则只能为ValueAnimator添加一个AnimatorUpdateListenerAnimatorUpdateListener可以监听Animator每个瞬间的变化取出对应的值。一个实例的代码如下 ValueAnimator animator ValueAnimator.ofInt(0, 100); // 没有target和property参数
animator.setDuration(5000);
animator.addUpdateListener(new AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator animation) {Integer value (Integer) animation.getAnimatedValue();System.out.println(-- value);}
});
animator.start(); 七TypeEvaluator主要用于ValueAnimator的ofObject()方法。根据文档中的介绍 Evaluators allow developers to create animations on arbitrary property types Evaluators允许开发者自定义动画参数。因此使用TypeEvaluator我们可以打破ObjectAnimator的动画范围禁锢创造我们自己的动画。大致代码如下 ValueAnimator animator ValueAnimator.ofObject(new TypeEvaluatorObject() {Overridepublic Object evaluate(float fraction, Object startValue, Object endValue) {return null;}
});
animator.start(); 八Interpolator插值器可以设置动画的效果。Animator内置了很多插值器如渐加速、渐减速、弹跳等等。插值器的种类可以在模拟器API DEMO应用的Views - Animation - Interpolator中查看。为Animator添加插值器只需要 animator.setInterpolator(new OvershootInterpolator()); 即可。 二、实现卫星菜单 实现卫星菜单我们主要使用了ObjectAnimator。先来介绍一下这个DEMO的效果如下组图开始的时候在屏幕左上角显示一个红色的按钮点击之后弹出一列子菜单每个子菜单之间的距离递增弹出的时间递减弹出时会有OverShoot效果点击每个子菜单都会弹出相应的Toast弹出菜单后再次点击红色按钮则收回所有子菜单。 下面贴出代码。 1 RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/android2 xmlns:toolshttp://schemas.android.com/tools3 android:layout_widthmatch_parent4 android:layout_heightmatch_parent5 android:backgroundcolor/white 6 7 !-- 上面的七张图片是七个子菜单 --8 ImageView9 android:idid/menuitem_07
10 stylestyle/SateliteMenu_Item_Theme
11 android:contentDescriptionstring/app_name
12 android:srcdrawable/item_07 /
13
14 ImageView
15 android:idid/menuitem_06
16 stylestyle/SateliteMenu_Item_Theme
17 android:contentDescriptionstring/app_name
18 android:srcdrawable/item_06 /
19
20 ImageView
21 android:idid/menuitem_05
22 stylestyle/SateliteMenu_Item_Theme
23 android:contentDescriptionstring/app_name
24 android:srcdrawable/item_05 /
25
26 ImageView
27 android:idid/menuitem_04
28 stylestyle/SateliteMenu_Item_Theme
29 android:contentDescriptionstring/app_name
30 android:srcdrawable/item_04 /
31
32 ImageView
33 android:idid/menuitem_03
34 stylestyle/SateliteMenu_Item_Theme
35 android:contentDescriptionstring/app_name
36 android:srcdrawable/item_03 /
37
38 ImageView
39 android:idid/menuitem_02
40 stylestyle/SateliteMenu_Item_Theme
41 android:contentDescriptionstring/app_name
42 android:srcdrawable/item_02 /
43
44 ImageView
45 android:idid/menuitem_01
46 stylestyle/SateliteMenu_Item_Theme
47 android:contentDescriptionstring/app_name
48 android:srcdrawable/item_01 /
49
50 !-- 最上层的红色按钮因为它显示在最上面因此布局代码在最后 --
51 ImageView
52 android:idid/menu_top
53 android:layout_width35.0dip
54 android:layout_height35.0dip
55 android:layout_marginLeft17.0dip
56 android:layout_marginTop17.0dip
57 android:contentDescriptionstring/app_name
58 android:srcdrawable/top_toopen /
59
60 /RelativeLayout MainActivity布局代码 1 public class MainActivity extends Activity implements OnClickListener {2 private ImageView top; // 红色按钮3 // 七个子菜单的ID组成的数组4 private int[] ids new int[] { R.id.menuitem_01, R.id.menuitem_02, R.id.menuitem_03, R.id.menuitem_04, R.id.menuitem_05, R.id.menuitem_06, R.id.menuitem_07, };5 private ListImageView itemList; // 七个子菜单都加到List中6 private boolean isMenuOpen; // 记录子菜单是否打开了7 8 Override9 protected void onCreate(Bundle savedInstanceState) {
10 super.onCreate(savedInstanceState);
11 setContentView(R.layout.activity_main);
12 initView();
13 }
14
15 private void initView() {
16 top (ImageView) findViewById(R.id.menu_top);
17 top.setOnClickListener(this);
18
19 itemList new ArrayListImageView();
20 for (int i 0; i ids.length; i) {
21 ImageView imageView (ImageView) findViewById(ids[i]);
22 imageView.setOnClickListener(this);
23 itemList.add(imageView);
24 }
25 }
26
27 Override
28 public void onClick(View v) {
29 switch (v.getId()) {
30 case R.id.menu_top:
31 if (!isMenuOpen) { // 如果子菜单处于关闭状态则使用Animator动画打开菜单
32 for (int i 0; i itemList.size(); i) {
33 // 子菜单之间的间距对着距离的增加而递增
34 ObjectAnimator animator ObjectAnimator.ofFloat(itemList.get(i), translationY, 0, (i 1) * (30 2 * i));
35 animator.setDuration((7 - i) * 100); // 最远的子菜单弹出速度最快
36 animator.setInterpolator(new OvershootInterpolator()); // 设置插值器
37 animator.start();
38 }
39 top.setImageResource(R.drawable.top_toclose);
40 isMenuOpen true;
41 } else { // 如果子菜单处于打开状态则使用Animator动画关闭菜单
42 for (int i 0; i itemList.size(); i) {
43 ObjectAnimator animator ObjectAnimator.ofFloat(itemList.get(i), translationY, (i 1) * (30 2 * i), 0);
44 animator.setDuration((7 - i) * 100);
45 animator.start();
46 }
47 top.setImageResource(R.drawable.top_toopen);
48 isMenuOpen false;
49 }
50 break;
51 default:
52 Toast.makeText(MainActivity.this, Item (itemList.indexOf(v) 1) Clicked..., Toast.LENGTH_SHORT).show();
53 break;
54 }
55 }
56 } MainActivity代码 三、扩展 使用属性动画可以实现的功能还有很多这里再追加一个“评分”的功能实现。直接显示成绩往往给人一种突兀的感觉所以我们想利用属性动画来实现一个数字变换的“成绩单”让成绩滚动显示同时越到最后滚动的越慢最后停止在真正的分数上。 思路我们需要用到ValueAnimator并用AnimatorUpdateListener作为动画的监听器监听动画的每一个动作并为成绩的TextView设置Text。 以下是代码。 1 RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/android2 xmlns:toolshttp://schemas.android.com/tools3 android:layout_widthmatch_parent4 android:layout_heightmatch_parent5 android:backgroundcolor/white 6 7 TextView8 android:idid/main_mark9 android:layout_widthwrap_content
10 android:layout_heightwrap_content
11 android:layout_centerInParenttrue
12 android:textColor#ff0000
13 android:textSize65.0sp /
14
15 /RelativeLayout MainActivity布局代码 1 public class MainActivity extends Activity {2 private TextView mark;3 private static final int REAL_MARK 96;4 5 Override6 protected void onCreate(Bundle savedInstanceState) {7 super.onCreate(savedInstanceState);8 setContentView(R.layout.activity_main);9 initView();
10 }
11
12 private void initView() {
13 mark (TextView) findViewById(R.id.main_mark);
14
15 ValueAnimator animator ValueAnimator.ofInt(0, REAL_MARK);
16 animator.setDuration(3000);
17 animator.setInterpolator(new DecelerateInterpolator());
18 animator.addUpdateListener(new AnimatorUpdateListener() {
19 Override
20 public void onAnimationUpdate(ValueAnimator animation) {
21 Integer value (Integer) animation.getAnimatedValue();
22 mark.setText(value );
23 }
24 });
25 animator.start();
26 }
27 } MainActivity代码 转载于:https://www.cnblogs.com/blog-wzy/p/5324316.html