完全自定义控件-自定义雷达扫描控件(学习Shader、Matrix)
elply1988
8年前
<h3><strong>自定义雷达扫描控件</strong></h3> <p>效果展示</p> <p><img src="https://simg.open-open.com/show/426c13bd6ba8ac359e974ba6eebf13c9.gif"></p> <p style="text-align:center">效果图</p> <h3><strong>涉及知识点</strong></h3> <p><strong>Shader类</strong></p> <p>在Android中,提供了Shader类专门用来渲染图像以及一些几何图形。</p> <ul> <li>使用Shader类进行图像渲染时,首先需要构建Shader对象,然后通过Paint的setShader()方法来设置渲染对象,最后将这个Paint对象绘制到屏幕上即可。</li> <li>Shader类包括了5个直接子类 <ul> <li>BitmapShader 图像渲染</li> <li>ComposeShader 混合渲染</li> <li>LinearGradient 线性渲染</li> <li>RadialGradient 环形渲染</li> <li>SweepGradient 梯度渲染<br> SweepGradient也称为扫描渲染,是指在某一中心以x轴正方向逆时针旋转一周而形成的扫描效果的渲染形式。 <pre> <code class="language-java">//坐标(cx,cy)决定了中心点的位置,会绕着该中心点进行360度旋转。color0表示的是起点的颜色位置,color1表示的是终点的颜色位置。 public SweepGradient(float cx, float cy, int[] colors, float[] positions) public SweepGradient(float cx, float cy, int color0, int color1)</code></pre> </li> </ul> </li> </ul> <p><a href="/misc/goto?guid=4959713336924280238" rel="nofollow,noindex">图像渲染的详细介绍</a></p> <p><strong>Matrix类</strong></p> <p>Matrix是一个矩阵,主要功能是坐标映射,数值转换。</p> <ul> <li>Matrix类有四种基本变换 <ul> <li>平移 setTranslate(); 平移意味着在x轴和y轴上简单地移动图像。</li> <li>缩放 setScale(); 它采用两个浮点数作为参数,分别表示在每个轴上所产生的缩放量。</li> <li>旋转 setRotate(); 它采用一个浮点数表示旋转的角度。围绕默认点(0,0),正数将顺时针旋转图像,而负数将逆时针旋转图像,其中默认点是图像的左上角。</li> <li>错切 setSkew(); 对于错切变换,在数学上又称为Shear mapping(可译为“剪切变换”)或者Transvection(缩并),它是一种比较特殊的线性变换。</li> </ul> </li> </ul> <p><a href="/misc/goto?guid=4959713337021483968" rel="nofollow,noindex">Matrix原理</a></p> <h3><strong>实现思路</strong></h3> <ol> <li>新建RadarView4类继承View</li> <li>重写onDraw()方法,画四个无锯齿空心圆环,两条直线</li> <li>画以最大圆为半径的实心渐变圆</li> <li>创建矩阵,旋转画布,重绘,并用Handler实现循环</li> </ol> <p><strong>1. 初始化数据</strong></p> <pre> <code class="language-java">public RadarView4(Context context) { this(context, null); } public RadarView4(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadarView4(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //为了避免在onDraw中重复创建对象,所以将一些初始化工作放入构造方法中来做 init(); //提交计划任务马上执行 mHandler.post(run); } private void init() { //创建圆环画笔 mCirclePaint = new Paint(); mCirclePaint.setColor(Color.GRAY); //设置画笔的宽度 mCirclePaint.setStrokeWidth(3); //设置抗锯齿模式 mCirclePaint.setAntiAlias(true); //设置画笔风格 mCirclePaint.setStyle(Paint.Style.STROKE); //创建扫描线画笔 mShaderPaint = new Paint(); mShaderPaint.setAntiAlias(true); //设置画笔风格为填充模式 mShaderPaint.setStyle(Paint.Style.FILL); }</code></pre> <p><strong>2. 开始绘制</strong></p> <pre> <code class="language-java">protected void onDraw(Canvas canvas) { super.onDraw(canvas); w = getMeasuredWidth();//获取view的宽度 h = getMeasuredHeight();//获取view的高度 //以中点为圆心 canvas.drawCircle(w / 2, h / 2, w / 12, mCirclePaint); canvas.drawCircle(w / 2, h / 2, w / 6, mCirclePaint); canvas.drawCircle(w / 2, h / 2, w / 4, mCirclePaint); canvas.drawCircle(w / 2, h / 2, w / 3, mCirclePaint); //画两条直线 canvas.drawLine(w / 2 - w / 3, h / 2, w / 2 + w / 3, h / 2, mCirclePaint); canvas.drawLine(w / 2, h / 2 - w / 3, w / 2, h / 2 + w / 3, mCirclePaint); //避免重复创建对象 if (mShader == null) //新建扫描渲染,扫描边由透明->红色进行渐变 mShader = new SweepGradient(w / 2, h / 2, Color.TRANSPARENT, getResources().getColor(R.color.RED)); //设置渲染对象 mShaderPaint.setShader(mShader); //指定画布的当前矩阵 canvas.concat(mMatrix); //画一个扫描图像 canvas.drawCircle(w / 2, h / 2, w / 3, mShaderPaint); }</code></pre> <p><strong>3.通过Handler循环绘制实现转动</strong></p> <pre> <code class="language-java">private Handler mHandler = new Handler(); Runnable run = new Runnable() { @Override public void run() { start++; mMatrix = new Matrix(); //为矩阵设置旋转坐标 mMatrix.setRotate(start, w / 2, h / 2); //刷新ui postInvalidate(); //如果到了360度,则重新开始 start = start == 360 ? 0 : start; //延迟执行 postDelayed(this, 10); } };</code></pre> <p>这里是 <a href="/misc/goto?guid=4959713337098573703" rel="nofollow,noindex">项目地址</a> 。</p> <p>参考</p> <p><a href="/misc/goto?guid=4959713337186134518" rel="nofollow,noindex">http://blog.csdn.net/itjianghuxiaoxiong/article/details/50207009</a></p> <p><a href="/misc/goto?guid=4959713337265743095" rel="nofollow,noindex">http://www.jianshu.com/p/4918034e3f0e#</a></p> <p><a href="/misc/goto?guid=4959713337341851043" rel="nofollow,noindex">http://blog.csdn.net/sahadev_/article/details/50432764</a></p> <p> </p> <p>来自:http://www.jianshu.com/p/954982ad3385</p> <p> </p>