欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-04-13 22:49:17
本文实例为大家分享了android雷达扫描效果的具体代码,供大家参考,具体内容如下 效果图 知识点提要 shader 矩阵matrix 属性动...

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

效果图

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

知识点提要

  • 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>

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