国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

支付寶咻一咻怎么用 Android幫你實現咻一咻

2020-04-11 10:50:18
字體:
來源:轉載
供稿:網友

對于之前最火的無外乎集五福了,而五福除了加十個好友獲得外,最直接的途徑就是支付寶的咻一咻了。那么咻一咻具體有哪些實現方式呢?下面我們將一一介紹這幾種思路的實現過程。

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>

以上就是本文的詳細內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 方正县| 长海县| 高要市| 海淀区| 合山市| 广元市| 南川市| 苏尼特右旗| 金沙县| 东丽区| 甘南县| 连南| 通州市| 射洪县| 大渡口区| 宜宾市| 祁东县| 东平县| 准格尔旗| 宕昌县| 龙门县| 榆中县| 佛学| 石狮市| 江达县| 安国市| 榆社县| 张家口市| 尼玛县| 平舆县| 固安县| 大理市| 闻喜县| 宁波市| 永兴县| 陈巴尔虎旗| 夏邑县| 中西区| 中阳县| 盱眙县| 西乌|