使用属性动画实现仿支付宝咻一咻功能

第一步:先画一个自定义圆。

public class Xiu3 extends View {

    private int n;
    private Paint paint;
    private int r;

    public Xiu3(Context context) {
        super(context);
        init();
    }

    public int getR() {
        return r;
    }

    public void setR(int r) {
        this.r = r;
        invalidate();
    }

    public Xiu3(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public Xiu3(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
         //extress = 0;
        //设置圆的数目
        n = 4;
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(4);
    }

    public Paint getPaint() {
        return paint;
    }

    public void setPaint(Paint paint) {
        this.paint = paint;
    }

    public final static Property<Xiu3,Integer> R=new Property<Xiu3, Integer>(Integer.class,"r") {
       @Override
       public Integer get(Xiu3 object) {
           return object.getR();
       }

       @Override
       public void set(Xiu3 object, Integer value) {
           //super.set(object, value);
           object.setR(value);
       }
   };
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /*int r1= getWidth();
        int r2= getHeight();
        r = Math.min(r1,r2);*/
        canvas.drawCircle(getWidth()/2,getHeight()/2, r/2,paint);
    }

自定义圆中设置Property<Xiu3,Integer> 属性中设置set,get方法在set方法中调用invalidate重新绘制画布

然后在属性动画中就能使用了

第二步:使用groupview在view中添加上面的view。

然后写属性动画。上面的view涉及到2中属性变化1是alpha透明度变化我设置为1-0.1然后是r的变化是0-你想要的变成的r

   List<AnimatorSet> sets=new ArrayList<>();
    public void startchildani(Xiu3 xiu){
        AnimatorSet set= new AnimatorSet();
        ObjectAnimator animator1=ObjectAnimator.ofInt(xiu,"r",0,xiu.getWidth());
        animator1.setRepeatCount(ValueAnimator.INFINITE);
        ObjectAnimator animator2=ObjectAnimator.ofFloat(xiu,"alpha",1f,0f);
        animator2.setRepeatCount(ValueAnimator.INFINITE);
        set.setInterpolator(new LinearInterpolator());
        set.play(animator1).with(animator2);
        set.setDuration(time);
        // AnimationSet set1;
        set.start();
        sets.add(set);
       // set.
    }
    publ

又集合储存方便之后的取消

然后依次画子view我使用了延时的操作实现这个。

 public void startani(){

        for (int i = 0; i <xiu3s.size() ; i++) {
            if (i==0){
              startchildani(xiu3s.get(i));
            }else{
                //delayed to start animation
                final int finalI = i;
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        startchildani(xiu3s.get(finalI));
                    }
                },time/xiu3s.size()*i);
            }

        }
    }
    public void stopani(){
       // set.end();
        removeCallbacks(null);
        for (int i = 0; i < sets.size(); i++) {
           // ((Xiu3) getChildAt(i)).clearAnimation();
            //stopanimation
            sets.get(i).end();
        }
    }
真是开始和停止的方法。为了防止在view关闭以后postdelay任然调用
最好在view关闭动画的时候移除postdelay不然你调用end动画任然会继续跑搞不好还会报空指针异常在activty关闭后。

即这个方法:

 removeCallbacks(null)
可以移除全部

然后是自定义属性的方法:我把代码一粘一看就明白了

    TypedArray array=getContext().obtainStyledAttributes(attrs,R.styleable.GroupXiu);
         time= array.getInteger(R.styleable.GroupXiu_animationtime,3000);
        //set circle color
        color = array.getColor(R.styleable.GroupXiu_circlecolor, Color.RED);
        circlenums = array.getInteger(R.styleable.GroupXiu_circlenums,3);
这是代码获取自定义属性的方法

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GroupXiu">
        <attr name="circlenums" format="integer"></attr>
        <attr name="animationtime" format="integer"></attr>
        <attr name="circlecolor" format="color"></attr>
    </declare-styleable>
</resources>
这是在attrs中设置自定属性然后就能在布局文件中的view中使用该属性


<com.cheerchip.xiuyixiu.GroupXiu
        android:id="@+id/xiu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:circlenums="6"
        app:circlecolor="#33f74141"
        app:animationtime="3000"
         />

这是布局文件中调用属性的方法然后在view中就可以使用了

最后我把整个groupview放上来:

public class GroupXiu extends RelativeLayout {
    //scroller also can change the value to do thia animation but i don't like
    //private Scroller scroller;
    /*private Xiu3 xiu1;
    private Xiu3 xiu2;
    private Xiu3 xiu3;*/
    private List<Xiu3> xiu3s=new ArrayList<>();
    private int time;
    private int color;
    private int circlenums;

    public GroupXiu(Context context) {
        super(context);
     //   init();
    }

    public GroupXiu(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public GroupXiu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public  void init(AttributeSet attrs){
       // LayoutInflater.from(getContext()).inflate(R.layout.xiu,this,false);
      //  scroller = new Scroller(getContext());
        //init the data
        TypedArray array=getContext().obtainStyledAttributes(attrs,R.styleable.GroupXiu);
         time= array.getInteger(R.styleable.GroupXiu_animationtime,3000);
        //set circle color
        color = array.getColor(R.styleable.GroupXiu_circlecolor, Color.RED);
        circlenums = array.getInteger(R.styleable.GroupXiu_circlenums,3);
       // time = 3000;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //add view to group
        LayoutParams params=new LayoutParams(getWidth(),getHeight());
        for (int i = 0; i < circlenums; i++) {
            Xiu3 xiu=new Xiu3(getContext());
            //set params
            addView(xiu,params);
            xiu3s.add(xiu);
            //set paint color you can also set the paint you like
            xiu.getPaint().setColor(color);
            //
        }
        //this is the test
      //  xiu1 = new Xiu3(getContext());
      //  xiu2 = new Xiu3(getContext());
      //  xiu3 = new Xiu3(getContext());
      //  addView(xiu2,params);
     //    addView(xiu3,params);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        LayoutParams params=new LayoutParams(getWidth(),getHeight());
        for (int i = 0; i <xiu3s.size() ; i++) {
            xiu3s.get(i).setLayoutParams(params);
        }
     /*   xiu1.setLayoutParams(params);
        xiu2.setLayoutParams(params);
        xiu3.setLayoutParams(params);*/
    }

    public void startani(){

        for (int i = 0; i <xiu3s.size() ; i++) {
            if (i==0){
              startchildani(xiu3s.get(i));
            }else{
                //delayed to start animation
                final int finalI = i;
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        startchildani(xiu3s.get(finalI));
                    }
                },time/xiu3s.size()*i);
            }

        }
    }
    List<AnimatorSet> sets=new ArrayList<>();
    public void startchildani(Xiu3 xiu){
        AnimatorSet set= new AnimatorSet();
        ObjectAnimator animator1=ObjectAnimator.ofInt(xiu,"r",0,xiu.getWidth());
        animator1.setRepeatCount(ValueAnimator.INFINITE);
        ObjectAnimator animator2=ObjectAnimator.ofFloat(xiu,"alpha",1f,0f);
        animator2.setRepeatCount(ValueAnimator.INFINITE);
        set.setInterpolator(new LinearInterpolator());
        set.play(animator1).with(animator2);
        set.setDuration(time);
        // AnimationSet set1;
        set.start();
        sets.add(set);
       // set.
    }
    public void stopani(){
       // set.end();
        removeCallbacks(null);
        for (int i = 0; i < sets.size(); i++) {
           // ((Xiu3) getChildAt(i)).clearAnimation();
            //stopanimation
            sets.get(i).end();
        }
    }
}

在activity中开启和关闭动画:

  xiu = ((GroupXiu) findViewById(R.id.xiu));
      //  startanimation( xiu);
    }

    public void startanimation(View view) {
        //Xiu3 xiu=((Xiu3) findViewById(R.id.xiu));
        if (scan){
            xiu.startani();
            scan=false;
        }else {
            xiu.stopani();
        }
就是这些了。


网上有很多在我看来都是复杂的数学公式看起来头昏眼花就自己想了一个写。

还有一个较为简单的是线条的扩散的代码单独一个view就完成了;

因为这个不需要颜色的渐变只要单一属性我使用valueanimotion完成的是几个圆圈线不停向外扩散



public class Xiu extends View {

    private Paint paint;
    private int n;
    private int excess;
    private int r;

    public Xiu(Context context) {
        super(context);
        init();
    }

    public int getExcess() {
        return excess;
    }

    public void setExcess(int excess) {
        this.excess = excess;
    }

    private void init() {
        //初始化圆的数目
        n = 4;
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(4);
    }

    public Xiu(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Xiu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
       int r1= getWidth();
       int r2= getHeight();
        r = Math.min(r1,r2);
        if (r ==r1){
            for (int i = 0; i <n ; i++) {
                canvas.drawCircle(r /2,getHeight()/2, r /2/n*4+excess,paint);
                canvas.drawCircle(r /2,getHeight()/2, r /2/n*3+excess,paint);
                canvas.drawCircle(r /2,getHeight()/2, r /2/n*2+excess,paint);
                canvas.drawCircle(r /2,getHeight()/2, r /2/n+excess,paint);
            }
        }
    }

    public void sartanimotion(){
        ValueAnimator animator=ValueAnimator.ofInt(0,r/4);
        animator.setInterpolator(new LinearInterpolator());
        animator.setDuration(2000);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                        excess= ((int) animation.getAnimatedValue());
                        invalidate();
            }
        });
        animator.start();
    }
就这些了。
项目地址
https://github.com/hfc123/XiuYiXiu1/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值