android 通过贝塞尔曲线 实现爱心点赞功能:
  ValueAnimatior:
核心功能:
    已知起点p0, 终p3,中间点 p1、p2  通过贝塞尔曲线 计算路径中各个点
案例1:  重力抛物线  
案例2:  爱心点赞功能

核心代码:LoveLayout 

package mk.denganzhi.com.zhiwenku;import java.util.Random;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.content.Context;import android.graphics.PointF;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;import android.widget.RelativeLayout;import mk.denganzhi.com.zhiwenku.BezierEvaluator;import mk.denganzhi.com.zhiwenku.R;public class LoveLayout extends RelativeLayout {    Drawable[] drawables = new Drawable[3];    private Random random = new Random();    private int dHeight;    private int dWidth;    private LayoutParams params;    private int mWidth;    private int mHeight;    public LoveLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    public LoveLayout(Context context) {        super(context);        init();    }    public LoveLayout(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // 必须在测量完毕以后才知道控件高度、和宽度        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();    }    private void init() {        //准备图片集合        drawables[0] = getResources().getDrawable(R.drawable.red);        drawables[1] = getResources().getDrawable(R.drawable.yellow);        drawables[2] = getResources().getDrawable(R.drawable.blue);        //得到图片的原始高度        dWidth = drawables[0].getIntrinsicWidth();        dHeight = drawables[0].getIntrinsicHeight();        params = new LayoutParams(dWidth, dHeight);        //将iv添加到父容器底部、水平居中位置        params.addRule(CENTER_HORIZONTAL);        params.addRule(ALIGN_PARENT_BOTTOM);    }    // 1. 第一步:  绘制ImageView 心形    public void addLoveIcon(){        //添加心形,并开始执行动画        final ImageView iv = new ImageView(getContext());        iv.setImageDrawable(drawables[random.nextInt(3)]);        //将iv添加到父容器底部、水平居中位置        iv.setLayoutParams(params);        addView(iv);        //开始属性动画:平移、透明度渐变、缩放动画        AnimatorSet set = getAnimator(iv);        //监听动画执行完毕,将iv移除或者复用        set.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);                removeView(iv);            }        });        set.start();    }    // 得到一个iv的动画集合    private AnimatorSet getAnimator(ImageView iv) {        //平移、透明度渐变、缩放动画        //1.alpha动画        ObjectAnimator alpha = ObjectAnimator.ofFloat(iv, "alpha", 0.3f,1f);        //2.缩放动画        ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.3f,1f);        ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.3f,1f);        //三个动画同时执行        AnimatorSet enter = new AnimatorSet();        enter.setDuration(600);        enter.playTogether(alpha,scaleX,scaleY);//enter.setTarget(iv);        //设置平移的曲线动画---贝塞尔曲线        // 2. 第二步启动估值器        ValueAnimator bezierAnimator = getBezierValueAnimator(iv);        AnimatorSet set = new AnimatorSet();        //同时依次执行 实现属性动画        set.playSequentially(enter,bezierAnimator);        set.setTarget(iv);        return set;    }    //得到一个贝塞尔曲线动画    private ValueAnimator getBezierValueAnimator(final ImageView iv) {        //根据贝塞尔公式确定四个点(起始点p0,拐点1p1,拐点2p2,终点p3)        PointF pointF0 = new PointF((mWidth-dWidth)/2, mHeight-dHeight);        PointF pointF3 = new PointF(random.nextInt(mWidth), 0);        PointF pointF1 = getPointF(1);        PointF pointF2 = getPointF(2);        BezierEvaluator evaluator = new BezierEvaluator(pointF1,pointF2);        ValueAnimator animator = ValueAnimator.ofObject(evaluator, pointF0,pointF3);        animator.addUpdateListener(new AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF pointF = (PointF) animation.getAnimatedValue();//                iv.setX(pointF.x);//                iv.setY(pointF.y);                iv.setX(pointF.x);                iv.setY(pointF.y);                Log.e("denganzhi1","坐标是:x"+ pointF.x +"  y:" + pointF.y);                iv.setAlpha(1-animation.getAnimatedFraction());//1~0 百分比            }        });        animator.setDuration(10000);        return animator;    }    private PointF getPointF(int i) {        PointF pointF = new PointF();        pointF.x = random.nextInt(mWidth);        if(i==1){            pointF.y = random.nextInt(mHeight/2)+mHeight/2;        }else{            pointF.y = random.nextInt(mHeight/2);        }        return pointF;    }}

 估值器:BezierEvaluator

package mk.denganzhi.com.zhiwenku;import android.animation.TypeEvaluator;import android.graphics.PointF;public class BezierEvaluator implements TypeEvaluator {private PointF pointF1;private PointF pointF2;public BezierEvaluator(PointF pointF1, PointF pointF2) {// TODO Auto-generated constructor stubthis.pointF1 = pointF1;this.pointF2 = pointF2;}@Overridepublic PointF evaluate(float t, PointF point0, PointF point3) {// b(t)=p0*(1-t)*(1-t)*(1-t)+3*p1*t*(1-t)*(1-t)+3*p2*t*t*(1-t)+p3*t*t*tPointF point = new PointF();point.x = point0.x*(1-t)*(1-t)*(1-t)+3*pointF1.x*t*(1-t)*(1-t)+3*pointF2.x*t*t*(1-t)+point3.x*t*t*t;point.y = point0.y*(1-t)*(1-t)*(1-t)+3*pointF1.y*t*(1-t)*(1-t)+3*pointF2.y*t*t*(1-t)+point3.y*t*t*t;return point;}}

 

MainActivity代码,使用控件:

package mk.denganzhi.com.zhiwenku;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity {    private LoveLayout loveLayout;    MyBazierLayout  myBazierLayout;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        loveLayout = (LoveLayout)findViewById(R.id.loveLayout);        myBazierLayout = findViewById(R.id.loveLayout2);    }    public void  start(View view){        loveLayout.addLoveIcon();      //  myBazierLayout.addLoveIcon();    }    public void translate(View view) {     //   myBazierLayout.translateFun();    }}

 MainActivity 的xml布局

                

效果图功能: 

android 通过贝塞尔曲线 实现爱心点赞功能_第1张图片

  源码地址:https://download.csdn.net/download/dreams_deng/12255079 

归纳:使用贝塞尔公式绘制曲线路径

package mk.denganzhi.com.zhiwenku;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.PointF;import android.graphics.drawable.BitmapDrawable;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.ImageView;public class TestActivity extends AppCompatActivity {    ImageButton mybtn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_test);        mybtn = (ImageButton) findViewById(R.id.mybtn);    }  boolean isFlag=false;    public void startAnimation(View view) {        WindowManager wm = (WindowManager) this                .getSystemService(Context.WINDOW_SERVICE);        final int width = wm.getDefaultDisplay().getWidth();        int height = wm.getDefaultDisplay().getHeight();        float startX= mybtn.getLeft();        float startY =mybtn.getTop();        PointF pointF0 = new PointF(startX, startY);        PointF pointF2 = new PointF(startX-50,startY-10);        PointF pointF3 = new PointF(startX-300,startY-500);                // 贝塞尔公式        PointF pointF4 = new PointF(width/2-mybtn.getWidth()/2,height/2-mybtn.getHeight()/2);        BezierEvaluator evaluator = new BezierEvaluator(pointF2,pointF3);        Log.e("denganzhi","startx:"+startX+"  startY:"+startY);        ValueAnimator animator = ValueAnimator.ofObject(evaluator, pointF0,pointF4);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF pointF = (PointF) animation.getAnimatedValue();//                iv.setX(pointF.x);//                iv.setY(pointF.y);                int scaleBeiShu= (width)/mybtn.getWidth();                mybtn.setX(pointF.x);                mybtn.setY(pointF.y);                Log.e("denganzhi1","坐标是:x"+ pointF.x +"  y:" + pointF.y +" scaleBeiShu:"+scaleBeiShu);                if(pointF.x<350){                    if(!isFlag){                        mybtn.setImageDrawable(new BitmapDrawable());/** *  .scaleY(2) :  放大到2倍 *  scaleYBy(1):  在原来基础上放大1倍,累加过程 * *  scrollTo *  scrollBy */                        mybtn.animate()                                .scaleYBy(1)                                .scaleXBy(scaleBeiShu)                                .setDuration(3000);                        isFlag=true;                    }                }           //     mybtn.setAlpha(1-animation.getAnimatedFraction());//1~0 百分比            }        });        animator.setDuration(1000);        animator.start();    }}

activity_test 布局:

<?xml version="1.0" encoding="utf-8"?>        

效果:

android 通过贝塞尔曲线 实现爱心点赞功能_第2张图片

 直接起点,终点, 中间2个点就可以使用贝塞尔曲线,绘制绘制轨迹

 问题就是:不知道它的点,知道点以后才知道轨迹 

更多相关文章

  1. Android让帧动画在结束时消失
  2. Android ActionBar中的按钮添加旋转动画
  3. Android分享界面制作(底部滑出动画)
  4. Android移动view动画问题
  5. android 动画之Scroller
  6. Android中Activity跳转和切换动画
  7. Android实现录音功能及播放语音功能

随机推荐

  1. android跳转至权限设置界面
  2. Android(安卓)ImageView使用网上图片资源
  3. android studio 57 MP3 音乐播放器 下载
  4. Android(安卓)Dialog对话框
  5. android 切换activity动画
  6. android 生成Excel文件
  7. android之activity间传输数据
  8. Android(安卓)滑动加载数据
  9. android单选框选择正确的答案
  10. API 25 (Android(安卓)7.1.1 API) webkit