ApiDemo--Animation/Seeking

来源:互联网 发布:财经日历软件 编辑:程序博客网 时间:2024/05/29 18:34

效果图这里写图片描述

自定义的小球

    public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener,Animator.AnimatorListener {        private static final float BALL_SIZE = 100f;        public final ArrayList<ShapeHolder> ballList = new ArrayList<>();        ValueAnimator bounceAnim = null;        ShapeHolder ball = null;        public MyAnimationView(Context context) {            this(context,null);        }        public MyAnimationView(Context context, AttributeSet attrs) {            this(context, attrs,0);        }        public MyAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {            super(context, attrs, defStyleAttr);            ball = addBall(200,0);        }        private ShapeHolder addBall(float x, float y) {            OvalShape oval = new OvalShape();            oval.resize(BALL_SIZE,BALL_SIZE);            ShapeDrawable drawable = new ShapeDrawable(oval);            ShapeHolder holder = new ShapeHolder(drawable);            holder.setX(x);            holder.setY(y);            int red = (int) (100 + Math.random() * 155);            int green = (int) (100 + Math.random() * 155);            int blue = (int) (100 + Math.random() * 155);            int color = 0xff000000 | red << 16 | green << 8 | blue;            Paint paint = drawable.getPaint();            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;            RadialGradient gradient = new RadialGradient(37.5f,12.5f,50f,color,darkColor, Shader.TileMode.CLAMP);            paint.setShader(gradient);            holder.setPaint(paint);            ballList.add(holder);            return holder;        }        private void creatAnimation() {            if (bounceAnim == null) {                bounceAnim = ObjectAnimator.ofFloat(ball,"y",ball.getY(),getHeight() - BALL_SIZE).setDuration(1500);                bounceAnim.setInterpolator(new BounceInterpolator());                bounceAnim.addUpdateListener(this);            }        }        public void startAnimation() {            creatAnimation();            bounceAnim.start();        }        public void seek(long seekTime) {            creatAnimation();            bounceAnim.setCurrentPlayTime(seekTime);        }        @Override        protected void onDraw(Canvas canvas) {            canvas.translate(ball.getX(),ball.getY());            ball.getShape().draw(canvas);        }        @Override        public void onAnimationStart(Animator animation) {        }        @Override        public void onAnimationEnd(Animator animation) {            ballList.remove((((ObjectAnimator)animation).getTarget()));        }        @Override        public void onAnimationCancel(Animator animation) {        }        @Override        public void onAnimationRepeat(Animator animation) {        }        @Override        public void onAnimationUpdate(ValueAnimator animation) {            invalidate();            long playTime = bounceAnim.getCurrentPlayTime();        }    }

这个自定义view的难点

1.怎么把一个圆变成一个小球呢,这就需要RadialGradient来做了,也就是一个渐变色的效果

 RadialGradient gradient = new RadialGradient(37.5f,12.5f,50f,color,darkColor, Shader.TileMode.CLAMP);paint.setShader(gradient);

2.如何让小球落下之后又谈起呢?

        private void creatAnimation() {            if (bounceAnim == null) {                bounceAnim = ObjectAnimator.ofFloat(ball,"y",ball.getY(),getHeight() - BALL_SIZE).setDuration(1500);                bounceAnim.setInterpolator(new BounceInterpolator());                bounceAnim.addUpdateListener(this);            }        }

具体的说就是** bounceAnim.setInterpolator(new BounceInterpolator());这一行代码实现的,这里面就牵扯了一个对象**Interpolator

Interpolator

AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速

AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速

AnticipateInterpolator 开始的时候向后然后向前甩

AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值

BounceInterpolator 动画结束的时候弹起

CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线

DecelerateInterpolator 在动画开始的地方快然后慢

LinearInterpolator 以常量速率改变

OvershootInterpolator 向前甩一定值后再回到原来位置

如果android定义的interpolators不符合你的效果也可以自定义interpolators,那么怎么自定义呢,对不起,我也不知道,各位看官们还是自行百度吧.
3.如何把SeekBarAnimation一起同步呢?

        public void seek(long seekTime) {            creatAnimation();            bounceAnim.setCurrentPlayTime(seekTime);        }

这就是关键了

说道这里其实也差不多了,下面就贴上效果图的代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent"   android:orientation="vertical"    tools:context="com.sdzn.fuzhuxian.apidemo.animation.AnimationSeeking">    <Button        android:id="@+id/btn_run"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="run"        />    <SeekBar        android:id="@+id/sb_seek"        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        /></LinearLayout>
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_animation_seeking);        LinearLayout container = (LinearLayout) findViewById(R.id.container);        final MyAnimationView animView = new MyAnimationView(this);        container.addView(animView);        findViewById(R.id.btn_run).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                animView.startAnimation();            }        });        SeekBar sb = (SeekBar) findViewById(R.id.sb_seek);        sb.setMax(DURATION);        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {            @Override            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                if (animView.getHeight() != 0) {                    animView.seek(progress);                }            }            @Override            public void onStartTrackingTouch(SeekBar seekBar) {            }            @Override            public void onStopTrackingTouch(SeekBar seekBar) {            }        });    }

最后贴上代码中的一个JavaBean

/** * auhor: BaiLong * date: 2017/2/24 * 一种数据结构,有形状和各种属性,可以用来定义 *形状是如何绘制的 */public class ShapeHolder {    private float x = 0 , y = 0;    private ShapeDrawable shape;    private int color;    private RadialGradient gradient;//环形渲染    private float alpha = 1.0f;    private Paint paint;    public ShapeHolder(ShapeDrawable s) {        shape = s;    }    public float getX() {        return x;    }    public void setX(float x) {        this.x = x;    }    public float getY() {        return y;    }    public void setY(float y) {        this.y = y;    }    public ShapeDrawable getShape() {        return shape;    }    public void setShape(ShapeDrawable shape) {        this.shape = shape;    }    public int getColor() {        return color;    }    public void setColor(int color) {        this.color = color;        shape.getPaint().setColor(color);    }    public RadialGradient getGradient() {        return gradient;    }    public void setGradient(RadialGradient gradient) {        this.gradient = gradient;    }    public Paint getPaint() {        return paint;    }    public void setPaint(Paint paint) {        this.paint = paint;    }    public float getAlpha() {        return alpha;    }    public void setAlpha(float alpha) {        this.alpha = alpha;        shape.setAlpha((int) (alpha * 255f + 0.5f));    }    public float getWidth() {        return shape.getShape().getWidth();    }    public void setWidth(float width) {        Shape s = shape.getShape();        s.resize(width, s.getHeight());    }    public float getHeight() {        return shape.getShape().getHeight();    }    public void setHeight(float height) {        Shape s = shape.getShape();        s.resize(s.getWidth(), height);    }}
0 0
原创粉丝点击