嘿嘿设计稿是这样子的,现在要求点击签到袋鼠往前跳一下.
具体逻辑其实跟我上次写的抖音点击生成心心是一样的:
1.自定义RelativeLayout:
public class Kangaroo extends RelativeLayout {
private Context context;
private LayoutParams params;
private Drawable[]icons =new Drawable[4];
private Interpolator[]interpolators =new Interpolator[4];
private int mWidth;
private int mHeight;
private int mLong;
private int i;
public Kangaroo(Context context, AttributeSet attrs) {
super(context, attrs);
this.context =context;
initView();
}
private void initView() {
}
public void addLoveView(float x, float y, int l) {
mWidth = (int) (x);
mHeight = (int) (y);
mLong =l;
//这里x,y是要跳的袋鼠的坐标,l是第一个袋鼠和第二个袋鼠之间的距离
final ImageView iv =new ImageView(context);
i =DimensionUtils.dip2px(context, 25);
params =new LayoutParams(i, i);
iv.setLayoutParams(params);
// 图片资源
iv.setImageDrawable(getResources().getDrawable(R.drawable.kangaroo));
addView(iv);
// 开启动画,并且用完销毁
AnimatorSet set = getAnimatorSet(iv);
set.start();
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
super.onAnimationEnd(animation);
removeView(iv);
}
});
}
/**
* 获取动画集合
*
* @param iv
*/
private AnimatorSet getAnimatorSet(ImageView iv) {
// 贝塞尔曲线动画
ValueAnimator bzier = getBzierAnimator(iv);
ValueAnimator bzier2 = getBzierAnimator2(iv);
AnimatorSet set2 =new AnimatorSet();
//依次跳,共两下
set2.playSequentially(bzier, bzier2);
set2.setTarget(iv);
return set2;
}
/**
* 贝塞尔动画
*/
private ValueAnimator getBzierAnimator(final ImageView iv) {
// TODO Auto-generated method stub
PointF[]PointFs = getPointFs(iv); // 5个点的坐标
BasEvaluator evaluator =new BasEvaluator(PointFs[1], PointFs[2]);
ValueAnimator valueAnim =ValueAnimator.ofObject(evaluator, PointFs[0], PointFs[2]);
valueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
PointF p = (PointF)animation.getAnimatedValue();
iv.setX(p.x);
iv.setY(p.y);
}
});
valueAnim.setTarget(iv);
valueAnim.setDuration(500);
return valueAnim;
}
private ValueAnimator getBzierAnimator2(final ImageView iv) {
// TODO Auto-generated method stub
PointF[]PointFs = getPointFs(iv); // 5个点的坐标
BasEvaluator evaluator =new BasEvaluator(PointFs[2], PointFs[3]);
ValueAnimator valueAnim =ValueAnimator.ofObject(evaluator, PointFs[2], PointFs[4]);
valueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
PointF p = (PointF)animation.getAnimatedValue();
iv.setX(p.x);
iv.setY(p.y);
}
});
valueAnim.setTarget(iv);
valueAnim.setDuration(400);
return valueAnim;
}
private PointF[]getPointFs(ImageView iv) {
// TODO Auto-generated method stub
PointF[]PointFs =new PointF[5];
PointFs[0] =new PointF(); // p0
PointFs[0].x = (mWidth);
PointFs[0].y =mHeight;
PointFs[1] =new PointF(); // p1
PointFs[1].x =mWidth +mLong /4;
PointFs[1].y =mHeight -100;
PointFs[2] =new PointF(); // p2
PointFs[2].x =mWidth +mLong /2;
PointFs[2].y =mHeight;
PointFs[3] =new PointF(); // p2
PointFs[3].x =mWidth +mLong *3 /4;
PointFs[3].y =mHeight -100;
PointFs[4] =new PointF(); // p2
PointFs[4].x =mWidth +mLong;
PointFs[4].y =mHeight;
return PointFs;
}
}
这里解释一下五个点坐标 PointF[]getPointFs这个方法:其实就是取距离,确定落地点和定点.落地点在距离的1/2处,最高点在1/4和3/4处.最低点高度和控件原坐标高度一致,最高点Y轴减一.
2.直接使用啦!我写了一个袋鼠跳的方法,点击事件调用我这个方法!传入的i是指第i个袋鼠
横向的一排袋鼠我用的是recycleview,所以获取控件的时候需要用layoutmanager,如果你是写固定的就没有那么麻烦了,直接拿就行了.
private void kangaroojump(int i) {
View view =gridLayoutManager.findViewByPosition(i);
final ImageView kangaroo1 =view.findViewById(R.id.kangaroo_icon);
View view2 =gridLayoutManager.findViewByPosition(i +1);
final ImageView kangaroo2 =view2.findViewById(R.id.kangaroo_icon);
final View coin =view2.findViewById(R.id.coin_icon);
int[]viewLocation =new int[2];
kangaroo1.getLocationInWindow(viewLocation);
int x =viewLocation[0]; // x 坐标
int y =viewLocation[1]; // y 坐标
int[]viewLocation2 =new int[2];
kangaroo2.getLocationInWindow(viewLocation2);
int x2 =viewLocation2[0]; // x 坐标
kangarooLayout.addLoveView(x, y, x2 -x);
kangaroo1.setVisibility(View.INVISIBLE);
new Thread() {
@Override
public void run() {
super.run();
try {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
@Override
public void run() {
kangaroo2.setVisibility(View.VISIBLE);
}
});
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}