android实现支付宝咻一咻的几种思路方法

android实现支付宝咻一咻的几种思路方法,第1张

概述支付宝咻一咻在过年的时候很火热。那么咻一咻具体有哪些实现方式呢?下面我们将一一介绍这几种思路的实现过程。

支付宝咻一咻在过年的时候很火热。那么咻一咻具体有哪些实现方式呢?下面我们将一一介绍这几种思路的实现过程。

1.自定义view实现咻一咻

那么这种实现方法需要掌握Canvas以及Paint几乎所有的方法。其对程序员的专业知识要求极高。

用该种方式实现的优点有:

㈠这种是最复杂的实现方法,但其兼容性最高,其支持AndroID的所有设备。

㈡其对内存要求不大,几乎不占用任何内存。

下面我们来看看是怎样实现其效果的:

public class XiuYiXiuVIEw extends VIEw {  /***   * 中心图片画笔   */  private Paint paint;  /***   * 水波圆圈画笔   */  private Paint circlePaint;  /***   * 用bitmap创建画布   */  private Bitmap bitmap;  /***   * 中心图片   */  private Bitmap imageBit;  /***   * 画布   */  private Canvas canvas;  /***   * 屏幕的宽   */  private int screenWIDth;  /***   * 屏幕的高   */  private int screenHeight;  /***   * 图片右上角坐标   */  private Point pointlefttop;  /***   * 图片右下角坐标   */  private Point pointRightBottom;  /***   * 记录圆圈   */  private List<LYJCircle> lyjCircleList;  /***   * 标记是否按下按钮,并且源泉是否扩散消失   */  private boolean isspread=false;  /***   * 默认没有按动时候的圆圈   */  private LYJCircle defaultCircle;  public XiuYiXiuVIEw(Context context,AttributeSet attrs) {    super(context,attrs);    this.lyjCircleList=new ArrayList<>();    screenWIDth=LYJUtils.getScreenWIDth((Activity) context);    screenHeight=LYJUtils.getScreenHeight((Activity) context);    bitmap = Bitmap.createBitmap(screenWIDth,screenHeight,Bitmap.Config.ARGB_8888); // 设置位图的宽高    canvas = new Canvas();    canvas.setBitmap(bitmap);    paint=new Paint(Paint.DITHER_FLAG);    paint.setAntiAlias(true);    circlePaint=new Paint(Paint.DITHER_FLAG);    circlePaint.setAntiAlias(true);    imageBit= BitmapFactory.decodeResource(getResources(),R.drawable.bwa_homepage_yuyin);    pointlefttop=new Point((screenWIDth/2)-(imageBit.getWIDth()/2),(screenHeight/2)-(imageBit.getHeight()/2));    pointRightBottom=new Point(pointlefttop.x+imageBit.getWIDth(),pointlefttop.y+imageBit.getHeight());    canvas.drawBitmap(imageBit,pointlefttop.x,pointlefttop.y,paint);    //取图片上的颜色    Palette.generateAsync(imageBit,new Palette.PaletteAsyncListener() {      @OverrIDe      public voID onGenerated(Palette palette) {        Palette.Swatch swatch1 = palette.getVibrantSwatch(); //充满活力的色板        circlePaint.setcolor(swatch1.getRgb());        circlePaint.setStyle(Paint.Style.stroke);        circlePaint.setstrokeWIDth(10);        circlePaint.setAlpha(100);        paint.setShadowLayer(15,swatch1.getRgb());//设置阴影效果        int[] mcolors = new int[] {//渲染颜色            color.transparent,swatch1.getRgb()        };        //范围,这里可以微调,实现你想要的渐变        float[] mpositions = new float[] {            0f,0.1f        };        Shader shader=new RadialGradIEnt(screenWIDth / 2,screenHeight / 2,imageBit.getWIDth() / 2 + 10,mcolors,mpositions,Shader.TileMode.MIRROR);        circlePaint.setShader(shader);        defaultCircle=new LYJCircle(screenWIDth / 2,imageBit.getWIDth() / 2 + 10);        clearScreenAndDrawList();        Message message = handler.obtainMessage(1);        handler.sendMessageDelayed(message,1000); //发送message      }    });  }  @OverrIDe  public boolean ontouchEvent(MotionEvent event) {    switch (event.getAction()){      case MotionEvent.ACTION_DOWN:        break;      case MotionEvent.ACTION_MOVE:        break;      case MotionEvent.ACTION_UP:        isspread=true;//是否按下图片        lyjCircleList.add(new LYJCircle(screenWIDth / 2,imageBit.getWIDth() / 2 + 10));        clearScreenAndDrawList();        invalIDate();        break;      default:        break;    }    return true;  }  private Handler handler = new Handler(){    public voID handleMessage(Message msg){      switch (msg.what) {        case 1:          //定时更新界面          clearScreenAndDrawList();          invalIDate();          Message message = handler.obtainMessage(1);          handler.sendMessageDelayed(message,200);      }      super.handleMessage(msg);    }  };  /**   * 清掉屏幕上所有的圆圈,然后画出集合里面的圆圈   */  private voID clearScreenAndDrawList() {    canvas.drawcolor(color.transparent,PorterDuff.Mode.CLEAR);    //判断是否按下图片,并且外圈执行完成没有。    if(!isspread){        circlePaint.setMaskFilter(null);        canvas.drawCircle(defaultCircle.getRoundX(),defaultCircle.getRoundY(),defaultCircle.geTradiuloop(),circlePaint);// 画线    }else{      for (LYJCircle lyjCircle : lyjCircleList) {        if(lyjCircle.getSpreadRadiu()==0){        }else if(lyjCircle.getSpreadRadiu()>(lyjCircle.geTradiu()+99)){          //如果圆圈扩散半径大于图片半径+99,那么设置边缘模糊,也就是淡出的效果          circlePaint.setMaskFilter(new BlurMaskFilter(5,BlurMaskFilter.Blur.OUTER));          canvas.drawCircle(lyjCircle.getRoundX(),lyjCircle.getRoundY(),lyjCircle.getSpreadRadiu(),circlePaint);// 画线        }else{          //不是则按正常的环形渲染来          circlePaint.setMaskFilter(null);          canvas.drawCircle(lyjCircle.getRoundX(),circlePaint);// 画线        }      }    }    canvas.drawBitmap(imageBit,paint);    //释放小时了的圆圈    for(int i=0;i<lyjCircleList.size();i++){      if(lyjCircleList.get(i).getSpreadRadiu()==0){        lyjCircleList.remove(i);      }    }    //如果没有点击图片发射出去的圆圈,那么就恢复默认缩放。    if(lyjCircleList.size()<=0){      isspread=false;    }  }  @OverrIDe  protected voID onDraw(Canvas canvas) {    canvas.drawBitmap(bitmap,null);  }}

圆类:

package com.example.liyuanjing.model;/** * Created by liyuanjing on 2016/2/3. */public class LYJCircle {  private int roundX;//圆中心点X坐标  private int roundY;//圆中心点Y坐标  private int radiu;//圆半径  private int currenTradiu;//当前radiu  private int lasTradiu;//历史radiu  private int spreadRadiu;//加速半径  private int[] speed=new int[]{6,6,6};//半径扩大速度。这里为匀速  private int speedLast=0;//记录历史值  public LYJCircle(int roundX,int roundY,int radiu){    this.roundX=roundX;    this.roundY=roundY;    this.radiu=radiu;    this.spreadRadiu=radiu;    this.currenTradiu=this.radiu;    this.lasTradiu=this.currenTradiu;  }  //获取半径  public int geTradiu() {    return radiu;  }  public voID seTradiu(int radiu) {    this.radiu = radiu;  }  //获取加速半径  public int getSpreadRadiu(){    if(speedLast>=speed.length){      return 0;    }    spreadRadiu+=speed[speedLast];    ++speedLast;    return spreadRadiu;  }  //获取循环缩放半径  public int geTradiuloop() {    if(currenTradiu==lasTradiu){      ++currenTradiu;    }else if(currenTradiu>lasTradiu){      if(currenTradiu>(radiu+20)){        currenTradiu=19+radiu;        lasTradiu=20+radiu;      }else{        lasTradiu=currenTradiu;        currenTradiu+=5;      }    }else{      if(currenTradiu<(radiu+9)){        currenTradiu=10+radiu;        lasTradiu=9+radiu;      }else{        lasTradiu=currenTradiu;        currenTradiu-=5;      }    }    return currenTradiu;  }  public int getRoundX() {    return roundX;  }  public int getRoundY() {    return roundY;  }}

看看其效果图:

你可以修改如下两个地方,会产生视觉上真真的波纹效果:

①支付宝的背景图片是淡红色,衬托了红色的波纹。当然了你也可以将画布设置为透明淡红色。

②其为填充圆圈渲染,不是我的边框渲染效果,你可以将circlePaint.setStyle(Paint.Style.stroke);换成Paint.Style.FILL.然后,微调shader的mpositions实现环形填充渐变。你也许会觉得,你看支付宝咻一咻圆圈d开的时候内圈有波纹也像外d开,其实那就是环形渐变,当你圆圈变大后,其渐变的范围也就变大了,自然你看到有颜色周围扩散的迹象。

2.属性动画实现咻一咻

其要掌握的只是基本只需要属性动画,在加一点线程方面有关的知识而已。

下面我们看看其实现步骤:

㈠自定义view实现一个圆即可,代码如下:

public class LYJCircleVIEw extends VIEw {  private Bitmap bitmap;  private Paint paint;  private Canvas canvas;  private int screenWIDth;  private int screenHeight;  private boolean isspreadFlag=false;//标记是否发射完成  public boolean isspreadFlag() {    return isspreadFlag;  }  public voID setIsspreadFlag(boolean isspreadFlag) {    this.isspreadFlag = isspreadFlag;  }  public LYJCircleVIEw(Context context,int wIDth,int height,int statusHeight) {    super(context);    screenWIDth= LYJUtils.getScreenWIDth((Activity) context);    screenHeight=LYJUtils.getScreenHeight((Activity) context);    bitmap = Bitmap.createBitmap(screenWIDth,Bitmap.Config.ARGB_8888); // 设置位图的宽高    canvas = new Canvas();    canvas.setBitmap(bitmap);    paint=new Paint(Paint.DITHER_FLAG);    paint.setAntiAlias(true);    paint.setcolor(color.RED);    paint.setStyle(Paint.Style.stroke);    paint.setstrokeWIDth(5);    paint.setAlpha(100);    paint.setShadowLayer(10,color.RED);    int[] mcolors = new int[] {        color.transparent,color.RED    };    float[] mpositions = new float[] {        0f,0.1f    };    Shader shader=new RadialGradIEnt(screenWIDth / 2,wIDth / 2 + 10,Shader.TileMode.MIRROR);    paint.setShader(shader);    canvas.drawCircle(screenWIDth / 2,(screenHeight - statusHeight) / 2,paint);    invalIDate();  }  @OverrIDe  protected voID onDraw(Canvas canvas) {    canvas.drawBitmap(bitmap,null);  }}

代码与上面差不多,就不注释了。
㈡实现Activity即可

public class XiuYiXiuActivity extends AppCompatActivity {  private Imagebutton mImagebutton;  private LYJCircleVIEw lyjCircleVIEw;  private relativeLayout relativeLayout;  private List<LYJCircleVIEw> lyjCircleVIEwList;  private int statusbarHeight;  private Animator anim;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.xiuyixiu_activity_main);    this.mImagebutton=(Imagebutton)findVIEwByID(R.ID.xiuyixiu_imagebutton);    this.relativeLayout=(relativeLayout)findVIEwByID(R.ID.xiuyixiu_relativelayout);    this.lyjCircleVIEwList=new ArrayList<>();    this.mImagebutton.setonClickListener(new VIEw.OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        lyjCircleVIEw.setVisibility(VIEw.GONE);//发射圆圈,即将循环动画VIEw隐藏        final LYJCircleVIEw item=new LYJCircleVIEw(XiuYiXiuActivity.this,mImagebutton.getWIDth(),mImagebutton.getHeight(),statusbarHeight);        Animator spreadAnim = AnimatorInflater.loadAnimator(XiuYiXiuActivity.this,R.animator.circle_spread_animator);        spreadAnim.addListener(new Animator.AnimatorListener() {          @OverrIDe          public voID onAnimationStart(Animator animation) {          }          @OverrIDe          public voID onAnimationEnd(Animator animation) {            item.setIsspreadFlag(true);//动画执行完成,标记一下          }          @OverrIDe          public voID onAnimationCancel(Animator animation) {          }          @OverrIDe          public voID onAnimationRepeat(Animator animation) {          }        });        spreadAnim.setTarget(item);        spreadAnim.start();        lyjCircleVIEwList.add(item);        relativeLayout.addVIEw(item);        relativeLayout.invalIDate();        Message message = handler.obtainMessage(1);        handler.sendMessageDelayed(message,10); //发送message,定时释放LYJCircleVIEw      }    });  }  private Handler handler = new Handler(){    public voID handleMessage(Message msg){      switch (msg.what) {        case 1:          for(int i=0;i<lyjCircleVIEwList.size();i++){            if(lyjCircleVIEwList.get(i).isspreadFlag()){              relativeLayout.removeVIEw(lyjCircleVIEwList.get(i));              lyjCircleVIEwList.remove(i);              relativeLayout.invalIDate();            }          }          if(lyjCircleVIEwList.size()<=0){            lyjCircleVIEw.setVisibility(VIEw.VISIBLE);          }          Message message = handler.obtainMessage(1);          handler.sendMessageDelayed(message,10);      }      super.handleMessage(msg);    }  };  @OverrIDe  public voID onWindowFocusChanged(boolean hasFocus) {    super.onWindowFocusChanged(hasFocus);    //获取状态栏高度    Rect frame = new Rect();    getwindow().getDecorVIEw().getwindowVisibledisplayFrame(frame);    statusbarHeight = frame.top;    this.mImagebutton.post(new Runnable() {      @OverrIDe      public voID run() {        lyjCircleVIEw = new LYJCircleVIEw(XiuYiXiuActivity.this,statusbarHeight);        relativeLayout.addVIEw(lyjCircleVIEw);        relativeLayout.postInvalIDate();        // 加载动画        anim = AnimatorInflater.loadAnimator(XiuYiXiuActivity.this,R.animator.circle_scale_animator);        anim.addListener(new Animator.AnimatorListener() {          @OverrIDe          public voID onAnimationStart(Animator animation) {          }          @OverrIDe          public voID onAnimationEnd(Animator animation) {            anim.start();//循环执行动画          }          @OverrIDe          public voID onAnimationCancel(Animator animation) {          }          @OverrIDe          public voID onAnimationRepeat(Animator animation) {          }        });        anim.setTarget(lyjCircleVIEw);        anim.start();      }    });  }}

㈢布局文件代码如下:

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:ID="@+ID/xiuyixiu_relativelayout"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent">  <Imagebutton    androID:ID="@+ID/xiuyixiu_imagebutton"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_centerInParent="true"    androID:background="@drawable/bwa_homepage_yuyin"/></relativeLayout>

当然上面两个实现方法,我都只设置圆边框,没有填充,你可以设置为填充后,在微调渐变值。

其属性动画文件circle_scale_animator.xml:

<?xml version="1.0" enCoding="utf-8"?><set xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:ordering="together">  <objectAnimator    androID:duration="1000"    androID:propertyname="scaleX"    androID:valueFrom="1.0"    androID:valueto="1.2"    androID:valueType="floatType">  </objectAnimator>  <objectAnimator    androID:duration="1000"    androID:propertyname="scaleY"    androID:valueFrom="1.0"    androID:valueto="1.2"    androID:valueType="floatType">  </objectAnimator>  <objectAnimator    androID:startOffset="1000"    androID:duration="1000"    androID:propertyname="scaleX"    androID:valueFrom="1.2"    androID:valueto="1.0"    androID:valueType="floatType">  </objectAnimator>  <objectAnimator    androID:startOffset="1000"    androID:duration="1000"    androID:propertyname="scaleY"    androID:valueFrom="1.2"    androID:valueto="1.0"    androID:valueType="floatType">  </objectAnimator></set>

另一个circle_spread_animator.xml为:

<?xml version="1.0" enCoding="utf-8"?><set xmlns:androID="http://schemas.androID.com/apk/res/androID">  <objectAnimator    androID:duration="1000"    androID:propertyname="scaleY"    androID:valueFrom="1.0"    androID:valueto="2.0"    androID:valueType="floatType">  </objectAnimator>  <objectAnimator    androID:duration="1000"    androID:propertyname="scaleX"    androID:valueFrom="1.0"    androID:valueto="2.0"    androID:valueType="floatType">  </objectAnimator></set>

其效果图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android实现支付宝咻一咻的几种思路方法全部内容,希望文章能够帮你解决android实现支付宝咻一咻的几种思路方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147866.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存