Android Shader应用开发之雷达扫描效果

发布时间 - 2026-01-11 02:21:36    点击率:

本文实例为大家分享了Android雷达扫描效果的具体代码,供大家参考,具体内容如下

效果图

知识点提要

  • Shader
  • 矩阵matrix
  • 属性动画

ShaderView3

package com.example.apple.shaderdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by apple on 2017/5/23.
 * 女神面部扫描
 */

public class ShaderView3 extends View {

  /**
   * 绘制扫描圈的笔
   */
  private Paint mSweepPaint;
  /**
   * 绘制女神bitmap的笔
   */
  private Paint mBitmapPaint;
  /**
   * 这个自定义View的宽度,就是你在xml布局里面设置的宽度(目前不支持)
   */
  private int mWidth;
  /**
   * 女神图片
   */
  private Bitmap mBitmap;
  /**
   * 雷达扫描旋转角度
   */
  private int degrees = 0;
  /**
   * 用于控制扫描圈的矩阵
   */
  Matrix mSweepMatrix = new Matrix();
  /**
   * 用于控制女神Bitmap的矩阵
   */
  Matrix mBitmapMatrix = new Matrix();
  /**
   * 着色器---生成扫描圈
   */
  private SweepGradient mSweepGradient;
  /**
   * 图片着色器
   */
  private BitmapShader mBitmapShader;
  private float mScale;

  public ShaderView3(Context context) {
    super(context);
    init();
  }

  public ShaderView3(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  /**
   * 属性动画,必须有setXxx方法,才可以针对这个属性实现动画
   *
   * @param degrees
   */
  public void setDegrees(int degrees) {
    this.degrees = degrees;
    postInvalidate();//在主线程里执行OnDraw
  }

  private void init() {
//    1.准备好画笔
    mSweepPaint = new Paint();
    mBitmapPaint = new Paint();
//    2.图片着色器
    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ccc);
    mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//    3.将图片着色器设置给画笔
    mBitmapPaint.setShader(mBitmapShader);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//    获取这个自定义view的宽高,注意在onMeasure里获取,在构造函数里得到的是0
    mWidth = getMeasuredWidth();
//    根据你所设置的view的尺寸和bitmap的尺寸计算一个缩放比例,否则的话,得到的图片是一个局部,而不是一整张图片
    mScale = (float) mWidth / (float) mBitmap.getWidth();
//    4.梯度扫描着色器
    mSweepGradient = new SweepGradient(mWidth / 2, mWidth / 2, new int[]{Color.argb(200, 200, 0, 0), Color.argb(10, 30, 0, 0)}, null);
//    5.将梯度扫描着色器设置给另外一支画笔
    mSweepPaint.setShader(mSweepGradient);


  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
//    迫不得已的时候,才在onDraw方法写代码,能提前准备的要在之前去准备,
//    不要写在onDraw里面,因为onDraw会不停地刷新绘制,写的代码越多,越影响效率


//    将图片缩放至你指定的自定义View的宽高
    mBitmapMatrix.setScale(mScale, mScale);
    mBitmapShader.setLocalMatrix(mBitmapMatrix);

//   设置扫描圈旋转角度
    mSweepMatrix.setRotate(degrees, mWidth / 2, mWidth / 2);
    mSweepGradient.setLocalMatrix(mSweepMatrix);

//    5. 使用设置好图片着色器的画笔,画圆,先画出下层的女神图片,在画出上层的扫描图片
    canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, mBitmapPaint);
    canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, mSweepPaint);


  }
}

外部调用

package com.example.apple.shaderdemo;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.LinearInterpolator;

public class MainActivity extends AppCompatActivity {

  private ShaderView3 mShaderView;
  int degrees = 0;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mShaderView = (ShaderView3) findViewById(R.id.sv);

    mShaderView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        ObjectAnimator degrees = ObjectAnimator.ofInt(mShaderView, "degrees", 0, 360);
        degrees.setInterpolator(new LinearInterpolator());
        degrees.setDuration(10000);
        degrees.setRepeatCount(ValueAnimator.INFINITE);
        degrees.start();
        /* new Thread(new Runnable() {
          @Override
          public void run() {
            while (degrees <= 360) {
              degrees += 1;
              mShaderView.setDegrees(degrees);

              try {
                Thread.sleep(30);
              } catch (InterruptedException e) {
                e.printStackTrace();
              }
            }


          }
        }).start();

        degrees = 0;
        mShaderView.setDegrees(degrees);*/


      }
    });
  }
}

XML布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.apple.shaderdemo.MainActivity">

  <com.example.apple.shaderdemo.ShaderView3
    android:id="@+id/sv"
    android:layout_width="300dp"
    android:layout_height="300dp"
    />

</LinearLayout>

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


# Android  # 雷达扫描  # Android应用中使用ContentProvider扫描本地图片并显示  # Android实现扫描和生成二维码  # Android实现扫描二维码功能  # Android studio 实现手机扫描二维码功能  # Android如何实现扫描和生成二维码  # Android银行卡扫描获取银行卡号  # Android实现银行卡号扫描识别功能  # Android 6.0 扫描不到 Ble 设备需开启位置权限的方法  # Android手机(设备)连接扫描枪扫码遇到的问题  # Android编程实现wifi扫描及连接的方法  # Android实现支付宝AR扫描动画效果  # Android 二维码扫描和生成二维码功能  # Android 开机应用扫描相关总结  # 着色器  # 自定义  # 画出  # 的是  # 是一个  # 你在  # 一支  # 要在  # 才可以  # 迫不得已  # 越多  # 你所  # 不支持  # 大家分享  # 写在  # 具体内容  # 整张  # 大家多多  # 而不是  # 不停地 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】  大型企业网站制作流程,做网站需要注册公司吗?  javascript中对象的定义、使用以及对象和原型链操作小结  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  使用spring连接及操作mongodb3.0实例  如何续费美橙建站之星域名及服务?  Android自定义控件实现温度旋转按钮效果  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  详解jQuery停止动画——stop()方法的使用  Laravel API资源类怎么用_Laravel API Resource数据转换  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  如何注册花生壳免费域名并搭建个人网站?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  python中快速进行多个字符替换的方法小结  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  重庆市网站制作公司,重庆招聘网站哪个好?  如何在阿里云通过域名搭建网站?  在线制作视频的网站有哪些,电脑如何制作视频短片?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言  青岛网站建设如何选择本地服务器?  详解Android中Activity的四大启动模式实验简述  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  Laravel如何使用Sanctum进行API认证?(SPA实战)  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  香港服务器如何优化才能显著提升网站加载速度?  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】  网站制作价目表怎么做,珍爱网婚介费用多少?  Laravel如何使用Livewire构建动态组件?(入门代码)  简历在线制作网站免费版,如何创建个人简历?  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  如何用狗爹虚拟主机快速搭建网站?  Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  文字头像制作网站推荐软件,醒图能自动配文字吗?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  Windows Hello人脸识别突然无法使用  JavaScript如何操作视频_媒体API怎么控制播放