美文网首页Android开发自定义控件
自定义View-第十七步:水波效果RadialGradient

自定义View-第十七步:水波效果RadialGradient

作者: crossroads | 来源:发表于2017-02-17 10:48 被阅读74次

    前言

    根据启舰大大 的博客所学习的自定义View。

    一、RadialGradient详解

    RadialGradient的意思是放射渐变,即它会向一个放射源一样,从一个点开始向外从一个颜色渐变成另一种颜色;

    //两色渐变
    RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
    //多色渐变
    RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)
    
    • (centerX ,centerY):渐变中心点坐标(x,y)
    • radius:渐变半径
    • centerColor:渐变的起始颜色,即渐变中心点的颜色,取值类型必须是八位的0xAARRGGBB色值!透明底Alpha值不能省略,不然不会显示出颜色。
    • edgeColor:渐变结束时的颜色,即渐变圆边缘的颜色,同样,取值类型必须是八位的0xAARRGGBB色值!
    • TileMode:与我们前面讲的各个Shader一样,用于指定当控件区域大于指定的渐变区域时,空白区域的颜色填充方式。

    二、小试牛刀

            //多色渐变
            int[]   colors = new int[]{0xffff0000,0xff00ff00,0xff0000ff,0xffffff00};
            float[] stops  = new float[]{0f,0.4f,0.6f,1f};
    
            paint.setShader(new RadialGradient(100,100,50,colors,stops, Shader.TileMode.CLAMP));
            canvas.drawCircle(100,100,100,paint);
    
            //双色渐变
            paint.setShader(new RadialGradient(300,300,50,0xffff0000, 0xff0000ff,Shader.TileMode.MIRROR));
            canvas.drawCircle(300,300,150,paint);
    
    效果图

    ps:看着第二个镜像是不是有点晕呢?嘿嘿,我也晕了,其实是由红变蓝,再由蓝变红,再由红变蓝......这样子继续下去,白色的那条线就是每一圈渐变的边界,(⊙o⊙)…有点不清晰,大家可以自己画个大大的圆试试

    三、水波纹效果

    先看效果图吧

    水波纹效果

    源码如下:

    public class MineView extends View {
        private Paint paint;
        float radius;
        ValueAnimator animator;
        int width; //控件的宽度
        int x, y; //当前触摸点的位置
    
        public MineView(Context context) {
            this(context, null);
        }
    
        public MineView(Context context, AttributeSet attrs) {
            super(context, attrs);
            paint = new Paint();
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
           //在这可以获取控件宽度,不要在初始化的时候获取,那时候是获取不到的
            width = getMeasuredWidth();
            animator = ValueAnimator.ofInt(50, width);
            animator.setDuration(1000);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    radius = (int) animation.getAnimatedValue();
                    updateShader();
                }
            });
    
            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
    
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    radius = 0;
                    updateShader();
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
    
                }
            });
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
            canvas.drawColor(Color.LTGRAY);
            canvas.drawCircle(x, y, radius, paint);
        }
    
        private void updateShader() {
            if (x > 0 && y > 0 && radius > 0) {
                //从零透明度逐渐变为绿色
                RadialGradient radialGradient = new RadialGradient(x, y, radius, 0x00FFFFFF, 0xFF00FF00, Shader.TileMode.CLAMP);
                paint.setShader(radialGradient);
            }
            postInvalidate();
        }
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (x != event.getX() || y != event.getY()) {
                x = (int) event.getX();
                y = (int) event.getY();
                radius = 50;
                updateShader();
            }
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    return true;
                case MotionEvent.ACTION_UP:
                    if (animator != null) {
                        if (animator.isRunning()) animator.cancel();
                        animator.start();
                    }
                    break;
            }
            return super.onTouchEvent(event);
        }
    }
    

    小知识

    getMeasureWidth()方法在measure()过程结束后就可以获取到了,
    而getWidth()方法要在layout()过程结束后才能获取到

    相关文章

      网友评论

        本文标题:自定义View-第十七步:水波效果RadialGradient

        本文链接:https://www.haomeiwen.com/subject/cnyhwttx.html