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.如何把SeekBar和Animation一起同步呢?
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
- ApiDemo--Animation/Seeking
- ApiDemo - View -Animation 学习
- APIDemo
- Android ApiDemo学习(四)Views——1 animation
- Android ApiDemo学习(五)Animation—— 2 Cloning
- Android ApiDemo学习(五)Animation—— 3 CustomEvaluator
- Android ApiDemo学习(五)Animation—— 5 Events
- Android官方ApiDemo中animation部分代码要点整理
- seeking missile
- Android ApiDemo学习(五)Animation—— 4 Default Layout Animation
- Android ApiDemo学习(五)Animation—— 6 Hide-Show Animation
- APIDemo学习笔记——Android上几种简单的Animation使用方法(二)
- APIDemo学习笔记——Android上几种简单的Animation使用方法(一)
- Android ApiDemo学习(五)Animation—— 1 Bouncing Balls
- Android ApiDemo学习(五)Animation——7 Layout Animations
- Android ApiDemo学习(四)Views——7 Layout Animation
- APIDemo学习笔记——Android上几种简单的Animation使用方法(一)
- APIDemo学习笔记——Android上几种简单的Animation使用方法(二)
- 第二周算法设计与分析:Search a 2D Matrix II
- XML基础
- React Native 封装原生UI组件并使用的流程(iOS)
- 夫妻性生活和谐的秘诀
- HTML中Array的用法
- ApiDemo--Animation/Seeking
- Ubuntu设置SSH免密登录(不同于CentOS)
- js锁定表头和列,实现类似execl锁定效果
- Android性能优化
- react生命周期
- 重启网卡出现提示:Error, some other host already uses address 10.10.10.25.
- quick-cocos 下载
- thinkpad x230i 笔记本安装win2003操作系统方法
- 十大Intellij IDEA快捷键