支付宝咻一咻怎么用 Android帮你实现咻一咻

对于之前最火的无外乎集五福了,而五福除了加十个好友获得外,最直接的途径就是支付宝的咻一咻了。那么咻一咻具体有哪些实现方式呢?下面我们将一一介绍这几种思路的实现过程。

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, 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<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, 0, 0, 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,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<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, mImageButton.getWidth(), mImageButton.getHeight(), 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>

以上就是本文的详细内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • Android支付宝和微信支付集成

    场景 随着移动支付的兴起,在我们的app'中,会经常有集成支付的需求.这时候一般都会采用微信和支付宝的sdk 来集成 (一)支付宝支付 在使用支付宝支付的过程中,我们是在服务器端生成订单,客户端访问接口,并得到订单信息,调用接口支付,支付成功后支付宝会分别 异步调用服务器端,并向客户端返回支付结果. 开发步骤: ①注册支付宝账号--进行实名认证--提交审核资料--审核通过 支付宝无线快捷支付接口: b.alipay.com/order/productDetail.htm?productId=20

  • Android自定义View实现支付宝咻一咻效果

    本篇文章介绍自定义View配合属性动画来实现如下的效果 实现思路挺简单: 画一个半透明的圆 实现两种动画效果,点击时扩散和不点击时扩散回收 使用线程的方式将上面两步结合起来 首先看下画半透明圆的部分 public class ClickCircleView extends View { private Bitmap bitmap; private Paint paint; private Canvas canvas; private boolean isSpreadFlag = false;//

  • Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几个圆,然后执行的动画有个延迟效果,其实这些动画是放在一起执行的,熟悉属性动画的知道已经给我们提供了同步执行动画和顺序执行动画的实现api,也会会有人说这几个view就是在onDraw()方法中画几个圆,可能会说我还要继承容器view去onLayout()方法中这些子view添加在某个特定的区域,当然

  • Android开发之实现GridView支付宝九宫格

    先给大家展示下关于仿支付宝钱包首页中带有分割线的gridview,俗称九宫格 的效果图,怎么样是不是和你想象的一样啊.在你的预料之中就继续访问以下代码内容吧. 我们都知道ListView设置分割线是非常容易的,设置ListView的分割线颜色和宽度,只需要在布局中定义android:divider和android:dividerHeight属性即可.而GridView并没有这样的属性和方法,那我们改如何来做呢? 我们小编在做这个效果之前,也参考了其他的一些方案,比如说定义一个自定义的GridVi

  • Android app第三方支付宝支付接入教程

    支付宝的接入相对比较简单,看看支付宝官网的文档基本都能搞定,但是切记一点让你们的后台也要搞清楚支付宝的流程,重中之重. 1.注意事项 开发前一定要阅读支付宝官方文档 强烈建议签名等处理在后台处理,我这个是测试是在自己本地写的,不要吐槽 想获取支付宝合作商户ID,及支付宝公钥请点击支付宝链接,生成密钥及PKCS8转码工具在文档中 添加Android.permission.INTERNET权限和android.permission.ACCESS_NETWORK_STATE权限 要导入支付宝的包 2.

  • Android支付宝支付设计开发

    在移动支付领域,支付宝支付占用巨大份额,根据艾瑞咨询公布的报告数据:2014Q3,支付宝斩获了82.6%的市场份额,在移动支付的霸主地位越来越稳固.财付通支付的发力点在微信支付和手Q支付,在移动支付格局中取得了10.0%的市场份额,排名第二. 支付宝在移动支付领域的统治地位,使得我们有必要梳理支付宝移动开发流程.本文写作的目的就是梳理支付流程,从架构层面讲述如何在移动应用中嵌入支付宝支付功能,以及指出哪些地方存在开发陷阱. 准备       按照说明,首先需要申请支付宝支付账号.这方面根据网站说

  • Android中RecyclerView布局代替GridView实现类似支付宝的界面

    单纯使用GridView 通用的两种给GridView 添加分割线的方法:http://stackoverflow.com/questions/7132030/android-gridview-draw-dividers 给Gridview 添加分割线,也就是实现网格布局,不清楚谷歌为什么没有给Gridview 添加一个类似 ListView 的Divider 属性,因此就需要我们自己去添加分割线, 目前两种方法,第一种是 利用GridView 的  android:horizontalSpac

  • Android支付宝支付封装代码

    在做Android支付的时候肯定会用到支付宝支付, 根据官方给出的demo做起来非常费劲,所以我们需要一次简单的封装. 封装的代码也很简单,就是将官网给的demo提取出一个类来方便使用. public class Alipay { // 商户PID public static final String PARTNER = "123456789"; // 商户收款账号 public static final String SELLER = "qibin0506@gmail.co

  • Android波纹扩散效果之仿支付宝咻一咻功能实现波纹扩散特效

    今年春节晚会没看尽兴,被支付宝集福给添了一段插曲,朋友们都在那数定时间段不停的咻一咻,哇,我咻到一个敬业福,不可能的,哈哈.那么咻一咻功能基于程序代码是怎么实现的呢?下面我们小编给大家分享本教程帮助大家学习Android波纹扩散效果之仿支付宝咻一咻功能实现波纹扩散特效,具体内容如下所示: 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术不行,也太懒了 PS:这个view也是我模仿了人家的效果,参考了人家的思路写的,不是纯手撸,罪过罪过

  • Android仿支付宝支付从底部弹窗效果

    我们再用支付宝支付的时候,会从底部弹上来一个对话框,让我们选择支付方式等等,今天我们就来慢慢实现这个功能 效果图 实现 主界面很简单,就是一个按钮,点击后跳到支付详情的Fragment中 package com.example.hfs.alipayuidemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.wi

随机推荐