咻一咻 android代码,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 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

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

currentRadiu=10+radiu;

lastRadiu=9+radiu;

}else{

lastRadiu=currentRadiu;

currentRadiu-=5;

}

}

return currentRadiu;

}

public int getRoundX() {

return roundX;

}

public int getRoundY() {

return roundY;

}

}

看看其效果图:

5014ca6b2a42af34b2d9be339313b0b9.gif

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

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

②其为填充圆圈渲染,不是我的边框渲染效果,你可以将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

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();

}

});

}

}

㈢布局文件代码如下:

android:id="@+id/xiuyixiu_relativelayout"

android:layout_width="match_parent"

android:layout_height="match_parent">

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"/>

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

其属性动画文件circle_scale_animator.xml:

android:ordering="together">

android:duration="1000"

android:propertyName="scaleX"

android:valueFrom="1.0"

android:valueTo="1.2"

android:valueType="floatType">

android:duration="1000"

android:propertyName="scaleY"

android:valueFrom="1.0"

android:valueTo="1.2"

android:valueType="floatType">

android:startOffset="1000"

android:duration="1000"

android:propertyName="scaleX"

android:valueFrom="1.2"

android:valueTo="1.0"

android:valueType="floatType">

android:startOffset="1000"

android:duration="1000"

android:propertyName="scaleY"

android:valueFrom="1.2"

android:valueTo="1.0"

android:valueType="floatType">

另一个circle_spread_animator.xml为:

android:duration="1000"

android:propertyName="scaleY"

android:valueFrom="1.0"

android:valueTo="2.0"

android:valueType="floatType">

android:duration="1000"

android:propertyName="scaleX"

android:valueFrom="1.0"

android:valueTo="2.0"

android:valueType="floatType">

其效果图如下:

7e038d81fd753a794703bee474d512a4.gif

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值