好伤心啊,webm转化成的pdf在上居然无法正常播放,我要怎么给宝宝们展示动态效果呢,蓝瘦香菇...上截图~~
嗯啦嗯啦,安啦,那个在冒烟儿,是均匀分布的啦!
怎么实现的呢?so easy!
布局首先是个FrameLayout,里面有包含8个imageview,一起堆在左上角,布局文件如下:
然后在我们的页面里面把这些imageView放到一个集合里面:
private int[] resIds = {R.id.iv_a, R.id.iv_b, R.id.iv_c, R.id.iv_d, R.id.iv_e,
R.id.iv_f, R.id.iv_g, R.id.iv_h};
private List imageViews = new ArrayList<>();
for (int resId : resIds) {
ImageView imageView = findViewById(resId);
imageView.setOnClickListener(this);
imageViews.add(imageView);
}
然后对iv_a这个设置一个点击事件,点一下展开menu,再点一下关闭menu。
一言不合上代码....
先说垂直展开菜单这个,设置Y轴偏移量根据i值变化,就可以程序上图那种萌萌哒的状态啦:
private void openMenu() {
for (int i = 1; i < resIds.length; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViews.get(i), "translationY",
0F, i * 300F);
animator.setDuration(500);
animator.setInterpolator(new AccelerateInterpolator());
// animator.setStartDelay(i*300);
animator.start();
}
expand = true;
}
关上!把这个菜单关上就是把所有的偏移量从现在的偏移量恢复成0:
private void closeMenu() {
for (int i = 1; i < resIds.length; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(imageViews.get(i), "translationY",
i * 300F, 0F);
animator.setDuration(500);
animator.setInterpolator(new AccelerateInterpolator());
// animator.setStartDelay(i*300);
animator.start();
}
expand = false;
}
这里我解释一下 ObjectAnimator.ofFloat里面的几个参数,第一个参数是target,就是需要进行动画操作的目标,没错,就是这些imageView啦,第二个参数,需要改变的属性,没错,就是我们的Y轴偏移量TranslationY啦,后面的属性就是values,就是我们的属性值从哪个值变化到哪个值,可以清楚地看到展开菜单和关闭菜单的不同就是属性值的变化不同,展开是从0→i300,关闭时从i300→0。
setDuration就是动画从开始到结束这个时间长短。
setInterpolator就是动画的插值器,设置动画变化的规律,有9个默认的插值器,这里用的是默认的加速插值器AccelerateInterpolator,还有减速啊,回弹啊等等之类的,好的插值器链接参照:https://www.jianshu.com/p/88740cba25e6
一般插值器是为了让动画效果更接近现实,so,根据自身需要决定是否使用。
好,下一个,扇形展开菜单!
扇形的怎么展开呢?简单一看就是不仅有Y轴的偏移量还有X轴的偏移量!要让他呈扇形均匀展开,就是把扇形平均分成imageViews.size() - 1份,回顾一下数学:
弧度的定义:弧长等于圆半径长的弧所对的圆心角为1弧度,弧度没有单位。
即弧度=弧长/半径=l/r,因此,若弧度=π,弧长=πr=圆周的一半,此时恰好为一个半圆,圆心角180,也就是说π=180,1°=π/180
所以我们的角度计算公式为:
angle = (float) Math.PI / (2 * (imageViews.size() - 1));//(π/2)/(imageViews.size() - 1)
三角函数计算x轴y轴的偏移量:
float x = (float) (r * Math.sin(i * angle));
float y = (float) (r * Math.cos(i * angle));
不懂得同学请自己摸出草稿本画三角形
三角形的展开和收起动画:
private void angleOpenMenu(float angle, float r) {
for (int i = 1; i < resIds.length; i++) {
float x = (float) (r * Math.sin(i * angle));
float y = (float) (r * Math.cos(i * angle));
PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 0F, x);
PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", 0F, y);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViews.get(i),
translationX, translationY);
animator.setInterpolator(new AccelerateInterpolator());
animator.setDuration(500).start();
}
expand = true;
}
private void closeOpenMenu(float angle, float r) {
for (int i = 1; i < resIds.length; i++) {
float x = (float) (r * Math.sin(i * angle));
float y = (float) (r * Math.cos(i * angle));
PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", x, 0F);
PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", y, 0F);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViews.get(i),
translationX, translationY);
animator.setInterpolator(new AccelerateInterpolator());
animator.setDuration(500).start();
}
expand = false;
}
细心的同学可以看到里面多了个PropertyValuesHolder,这个是用于组合多个动画,也可以像垂直展开动画一样单独写,如果需要定义动画顺序,比如先Y轴便宜再X轴偏移,或者Z轴和Y轴一起偏移,就需要使用AnimatorSet。
简单说一下AnimatorSet:
AnimatorSet.playTogether//动画一起播放;
AnimatorSet.playSequentially//动画按照顺序播放;
AnimatorSet.play(translationX).with(translationY)//动画X和Y一起播放;
AnimatorSet.play(translationY).after(translationX)//动画Y在动画X之后执行
好,到此结束。
有不对的地方请指正,O(∩_∩)O谢谢。