显示

先分析

每次自由落体运动-过程a
从一个消息框到下一个消息框-过程b (由多个过程a组成)
获取屏幕上消息的的Y轴坐标,并不断更新数据结构-过程c
c+b就是整个动画
代码们
过程a: 一次自由落体
计算时间:


先求Y轴的初始速度X轴的速度
float singleTime= (float) ((-startVy+Math.sqrt(startVy*startVy+2*g*distanceY))/g);
startVx=distanceX/singleTime;
再算坐标
currentX= (int) (startX+currentVx*period1);
currentVy= (float) (startVy+g*period1);
currentY= (int) (startY+startVy*period1+g*period1*period1/2);
放在循环中形成动画
这里用surfaceview较好,用view的话会太卡顿
private void drawUI() {
Canvas canvas=holder.lockCanvas();
try{
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
canvas.drawBitmap(bitmap,currentX,currentY-bitmapHei,paint);
if(points!=null){
for(Point temp:points){
canvas.drawCircle(temp.x,temp.y,10,paint);
}
}
}catch (Exception e){
Log.e(TAG,"出错了");
}finally{
holder.unlockCanvasAndPost(canvas);
}
}
相信我,麻烦事慢慢做的时候最不麻烦!
过程b 用数据转换为动画

这里借用下图,一个过程b包含个过程a
多个过程a的组成
while(currentIndex<points.size()-1){
...
if(Math.abs(currentVy)<MAX_VY){
if(currentIndex==points.size()-2){
//结束了
resetBall();
break;
}
currentIndex++;
startVy=START_VY;//不断重置 v轴方向的速度
}
}
需要的数据
public void setPoints(List<Point>points){
this.points=points;
}
过程c:数据获取(然后把结果输入给过程b)
先获取
private void initPoints() {
map.clear();
int first=manager.findFirstCompletelyVisibleItemPosition();
int last=manager.findLastCompletelyVisibleItemPosition();//得到暂时可见的
for(int i=first;i<=last;i++){
View view=manager.findViewByPosition(i);
float distance;
if(i==first){
distance=0;
}else{
View previous=manager.findViewByPosition(i-1);
distance=view.getY()-previous.getY();
}
PointInfo pointInfo=new PointInfo(distance,infos.get(i).isMe);
map.put(i,pointInfo);
}
float startY=manager.findViewByPosition(first).getY();
entity=new LocationEntity(map,first,startY);//把距离差转换为坐标
mainScroll.setLocation(entity);
}
再更新
if(i>mainScroll.getLocationEntity().firstPosition&&
!mainScroll.getLocationEntity().getDistanceMap().containsKey(i)){//只往下获取
...
}
移动的偏移
这里用到的offsetTopAndBottom,在recyclerview的监听中
ballsurfaceView.offsetTopAndBottom(dy);
遇到的麻烦
view不断重画会很卡,用surfaceview替代
Canvas canvas=holder.lockCanvas();
try{
...
}catch (Exception e){
}finally{
holder.unlockCanvasAndPost(canvas);
}
动画的显示可能会很长,这里用到了scrollview当做父容器。
禁止滑动
surfaceview直接添加的话高度为零,需要放到一个LinearLayout当中
surfaceview的高度不应该是固定值
因为可利用数据只是屏幕内能看到的内容,所以需要不断更新数据,加入新的坐标点。这里偷下懒,对象引用传递就好了。
大功告成!
以上です。

网友评论