一個炫酷的仿雷達掃描和擴散效果——自定義View就是這麼簡單

codeGoogle發表於2017-07-13

高仿雷達掃描效果和仿水波紋中心擴散效果,手把手教你擼一個炫酷的自定義view。

於亞豪的部落格地址:

blog.csdn.net/androidstar…

我們先看效果圖吧

Markdown
Markdown

Markdown
Markdown

對於仿水波紋中心擴脈衝效果

思路

大家一看就應該知道,一張圖片在不斷的放大,且顏色漸變。那不就是自定義屬性動畫嗎

沒錯就是這麼神奇。ScaleAnimation+AlphaAnimation

  • 縮放動畫:

       //建立一個AnimationSet物件,引數為Boolean型,
     //true表示使用Animation的interpolator,false則是使用自己的
     animationSet = new AnimationSet(true);
     //引數1:x軸的初始值
     //引數2:x軸收縮後的值
     //引數3:y軸的初始值
     //引數4:y軸收縮後的值
     //引數5:確定x軸座標的型別
     //引數6:x軸的值,0.5f表明是以自身這個控制元件的一半長度為x軸
     //引數7:確定y軸座標的型別
     //引數8:y軸的值,0.5f表明是以自身這個控制元件的一半長度為x軸
     ScaleAnimation scaleAnimation = new ScaleAnimation(
            1, animation_size,1,animation_size,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
     scaleAnimation.setDuration(3000);
     animationSet.addAnimation(scaleAnimation);複製程式碼
  • 漸變動畫

     //建立一個AlphaAnimation物件,引數從完全的透明度,到完全的不透明
     AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
     //設定動畫執行的時間
     alphaAnimation.setDuration(3000);
     //將alphaAnimation物件新增到AnimationSet當中
     animationSet.addAnimation(alphaAnimation);
     //使用ImageView的startAnimation方法執行動畫
     animationSet.setFillAfter(true);
     animationSet.setInterpolator(new AccelerateInterpolator());
     animationSet.setAnimationListener(new AnimationListener() {
         public void onAnimationStart(Animation animation) {
         }
         public void onAnimationRepeat(Animation animation) {
         }
         public void onAnimationEnd(Animation animation) {
             imageview_01.startAnimation(animationSet);
         }
     });
     imageview_01.startAnimation(animationSet);複製程式碼

高仿雷達掃描效果

思路

  • 首先我們要確認要用什麼方式去實現

  • 佈局的擺放

  • 利用屬性動畫一張圖片或者是一個view在繞著中心點

  • 自定義View進行矩陣旋轉

Markdown
Markdown

效果實現

  • 自定義RelativeLayout進行擺設布

       protected void onDraw(Canvas canvas) {
              super.onDraw(canvas);    
              canvas.drawBitmap(bitmap, getWidth() / 2 - bitmap.getWidth() / 2, getHeight() / 2 - bitmap.getHeight() / 2, null);
              canvas.drawBitmap(bitmap1,  getWidth() / 2 - bitmap1.getWidth() / 2, getHeight() / 2 - bitmap1.getHeight() / 2, null);
              if(isSearching) invalidate();
          }複製程式碼
  • 動畫

      Rect rMoon = new Rect(getWidth()/2-bitmap2.getWidth(),getHeight()/2,getWidth()/2,getHeight()/2+bitmap2.getHeight());
                  canvas.rotate(offsetArgs,getWidth()/2,getHeight()/2);
                  canvas.drawBitmap(bitmap2,null,rMoon,null);
                  offsetArgs = offsetArgs + 3;複製程式碼

自定義CircleWaveDivergenceView:

/**
 * 類功能描述:</br>
 * 仿雷達掃描View
 * 部落格地址:http://blog.csdn.net/androidstarjack
 * 公眾號:終端研發部
 * @author yuyahao
 * @version 1.0 </p> 修改時間:</br> 修改備註:</br>
 */
public class CircleWaveDivergenceView extends RelativeLayout{

    public static final String TAG = "SearchDevicesView";
    public static final boolean D  = BuildConfig.DEBUG;
    public Context context;
    @SuppressWarnings("unused")
    private long TIME_DIFF = 1500;
    private float offsetArgs = 0;
    private boolean isSearching = false;
    private Bitmap bitmap;
    private Bitmap bitmap1;
    private Bitmap bitmap2;


    public boolean isSearching() {
        return isSearching;
    }

    public void setSearching(boolean isSearching) {
        this.isSearching = isSearching;
        offsetArgs = 0;
        invalidate();
    }

    public CircleWaveDivergenceView(Context context) {
        super(context);
        this.context = context;
        initBitmap();
    }

    public CircleWaveDivergenceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initBitmap();
    }

    public CircleWaveDivergenceView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        initBitmap();
    }

    private void initBitmap(){
        if(bitmap == null){
            bitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.gplus_search_bg));
        }
        if(bitmap1 == null){
            bitmap1 = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.locus_round_click));
        }
        if(bitmap2 == null){
            bitmap2 = Bitmap.createBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.gplus_search_args));
        }
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);    
        canvas.drawBitmap(bitmap, getWidth() / 2 - bitmap.getWidth() / 2, getHeight() / 2 - bitmap.getHeight() / 2, null);
        if(isSearching){
            Rect rMoon = new Rect(getWidth()/2-bitmap2.getWidth(),getHeight()/2,getWidth()/2,getHeight()/2+bitmap2.getHeight());
            canvas.rotate(offsetArgs,getWidth()/2,getHeight()/2);
            canvas.drawBitmap(bitmap2,null,rMoon,null);
            offsetArgs = offsetArgs + 3;
        }else{
            canvas.drawBitmap(bitmap2,  getWidth() / 2  - bitmap2.getWidth() , getHeight() / 2, null);
        }
        canvas.drawBitmap(bitmap1,  getWidth() / 2 - bitmap1.getWidth() / 2, getHeight() / 2 - bitmap1.getHeight() / 2, null);
        if(isSearching) invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {    
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:        
            handleActionDownEvenet(event);
            return true;
        case MotionEvent.ACTION_MOVE: 
            return true;
        case MotionEvent.ACTION_UP:
            return true;
        }
        return super.onTouchEvent(event);
    }

    private void handleActionDownEvenet(MotionEvent event){
        RectF rectF = new RectF(getWidth() / 2 - bitmap1.getWidth() / 2, 
                                getHeight() / 2 - bitmap1.getHeight() / 2, 
                                getWidth() / 2 + bitmap1.getWidth() / 2, 
                                getHeight() / 2 + bitmap1.getHeight() / 2);

        if(rectF.contains(event.getX(), event.getY())){
            if(D) Log.d(TAG, "click search device button");
            if(!isSearching()) {
                setSearching(true);
            }else{
                setSearching(false);
            }
        }
    }
}複製程式碼

最終實現效果:

image
image

程式碼並沒有很多,需要的同學可以下載github Demo體驗和學習。

專案Github連結地址

github.com/androidstar…

下載慢?CSDN下載連結:

download.csdn.net/detail/andr…

相信自己,沒有做不到的,只有想不到的

如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部

相關文章