栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

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

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

1.自定义View实现咻一咻

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

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

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

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

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

public class XiuYiXiuView extends View {
  
  private Paint paint;
  
  private Paint circlePaint;
  
  private Bitmap bitmap;
  
  private Bitmap imageBit;
  
  private Canvas canvas;
  
  private int screenWidth;
  
  private int screenHeight;
  
  private Point pointLeftTop;
  
  private Point pointRightBottom;
  
  private List 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, 0, 0, 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, screenHeight / 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, screenHeight / 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(), lyjCircle.getRoundY(),lyjCircle.getSpreadRadiu(), circlePaint);// 画线
 }
      }
    }
    canvas.drawBitmap(imageBit,pointLeftTop.x,pointLeftTop.y,paint);
    //释放小时了的圆圈
    for(int i=0;i

圆类:

package com.example.liyuanjing.model;


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,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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实现环形填充渐变。你也许会觉得,你看支付宝咻一咻圆圈弹开的时候内圈有波纹也像外弹开,其实那就是环形渐变,当你圆圈变大后,其渐变的范围也就变大了,自然你看到有颜色周围扩散的迹象。

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, screenHeight, 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, 0, 0, Color.RED);
    int[] mColors = new int[] {
 Color.TRANSPARENT,Color.RED
    };
    float[] mPositions = new float[] {
 0f, 0.1f
    };
    Shader shader=new RadialGradient(screenWidth / 2,screenHeight / 2,width / 2 + 10,mColors, mPositions,
 Shader.TileMode.MIRROR);
    paint.setShader(shader);
    canvas.drawCircle(screenWidth / 2, (screenHeight - statusHeight) / 2, width / 2 + 10, paint);
    invalidate();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(bitmap,0,0,null);
  }
}

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

public class XiuYiXiuActivity extends AppCompatActivity {
  private ImageButton mImageButton;
  private LYJCircleView lyjCircleView;
  private RelativeLayout relativeLayout;
  private List 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

㈢布局文件代码如下:




  



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

其属性动画文件circle_scale_animator.xml:



  
  
  
  
  
  
  
  


另一个circle_spread_animator.xml为:



  
  
  
  


其效果图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160895.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号