今天来实现这样的点赞效果:
自定义ViewGroup:
public class LoveLayout extends RelativeLayout {
private Interpolator[] mInterpolators;
private Random random = new Random();
private Drawable[] drawables;
private Drawable red;
private Drawable blue;
private Drawable yellow;
private int width;
private int height;
private int dWidth;
private int dHeight;
private ImageView loveImg;
public LoveLayout(Context context) {
this(context,null);
}
public LoveLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public LoveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
addLoveImg();
post(new Runnable() {
@Override
public void run() {
startImgAnim(loveImg);
loveImg.setVisibility(View.GONE);
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
addLoveImg();
post(new Runnable() {
@Override
public void run() {
if (dWidth != 0 && dHeight != 0){
dWidth = red.getIntrinsicWidth();
dHeight = red.getIntrinsicHeight();
}
startImgAnim(loveImg);
}
});
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
dWidth = red.getIntrinsicWidth();
dHeight = red.getIntrinsicHeight();
}
public void addLoveImg(){
initDrawable();
initInterpolator();
loveImg = new ImageView(getContext());
loveImg.setImageDrawable(drawables[random.nextInt(drawables.length)]);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(ALIGN_PARENT_BOTTOM);
params.addRule(CENTER_HORIZONTAL);
loveImg.setLayoutParams(params);
addView(loveImg);
}
private void startImgAnim(final ImageView loveImg) {
ObjectAnimator alphaAnim = ObjectAnimator
.ofFloat(loveImg,"alpha",0.3f,1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator
.ofFloat(loveImg,"scaleX",0.2f,1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator
.ofFloat(loveImg,"scaleY",0.2f,1.0f);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim,scaleXAnim,scaleYAnim);
set.setDuration(500);
set.setInterpolator(mInterpolators[random.nextInt(4)]);
//set.start();
//p1.y > p2.y
PointF p0 = new PointF(width/2-dWidth/2,height-dHeight);
PointF p1 = new PointF(random.nextInt(width),random.nextInt(height/2)+height/2);
PointF p2 = new PointF(random.nextInt(width),random.nextInt(height/2));
PointF p3 = new PointF(random.nextInt(width),0);
BezierEvaluator evaluator = new BezierEvaluator(p1,p2);
ValueAnimator animator = ValueAnimator.ofObject(evaluator,p0,p3);
animator.setDuration(2000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF pointF = (PointF) animation.getAnimatedValue();
loveImg.setX(pointF.x);
loveImg.setY(pointF.y);
float t = animation.getAnimatedFraction();
loveImg.setAlpha(1.0f - t*1.0f + 0.2f);
}
});
//animator.start();
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(set,animator);
animatorSet.start();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
removeView(loveImg);
}
});
}
private void initDrawable() {
red = getResources().getDrawable(R.drawable.pl_red);
blue = getResources().getDrawable(R.drawable.pl_blue);
yellow = getResources().getDrawable(R.drawable.pl_yellow);
drawables = new Drawable[3];
drawables[0] = red;
drawables[1] = blue;
drawables[2] = yellow;
}
private void initInterpolator() {
mInterpolators = new Interpolator[4];
mInterpolators[0] = new LinearInterpolator();// 线性
mInterpolators[1] = new AccelerateDecelerateInterpolator();// 先加速后减速
mInterpolators[2] = new AccelerateInterpolator();// 加速
mInterpolators[3] = new DecelerateInterpolator();// 减速
}
}
自定义估值器:
public class BezierEvaluator implements TypeEvaluator<PointF> {
private PointF point1, point2;
public BezierEvaluator(PointF pointF1, PointF pointF2) {
this.point1 = pointF1;
this.point2 = pointF2;
}
@Override
public PointF evaluate(float t, PointF p0, PointF p3) {
// t百分比, 0~1
PointF point = new PointF();
point.x = p0.x * (1 - t) * (1 - t) * (1 - t) //
+ 3 * point1.x * t * (1 - t) * (1 - t)//
+ 3 * point2.x * t * t * (1 - t)//
+ p3.x * t * t * t;//
point.y = p0.y * (1 - t) * (1 - t) * (1 - t) //
+ 3 * point1.y * t * (1 - t) * (1 - t)//
+ 3 * point2.y * t * t * (1 - t)//
+ p3.y * t * t * t;//
// 套用上面的公式把点返回
return point;
}
}
在布局中使用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.view_09.LoveLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>