一个炫酷的仿雷达扫描和扩散效果——自定义View就是这么简单

高仿雷达扫描效果和仿水波纹中心扩散效果,手把手教你撸一个炫酷的自定义view。

于亚豪的博客地址:

blog.csdn.net/androidstar…

我们先看效果图吧

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
效果实现
  • 自定义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

代码并没有很多,需要的同学可以下载github Demo体验和学习。

项目Github链接地址

github.com/androidstar…

下载慢?CSDN下载链接:

download.csdn.net/detail/andr…

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

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值