ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android 自定义水波纹点击效果Button

2021-06-01 15:55:22  阅读:269  来源: 互联网

标签:水波纹 canvas 自定义 int Button private event mPaint public


welcome

效果

;

技术基础思路

  • 自定义 Button
  • 自定义 Drawable

项目源码

点击查看详情

自定义button

其实这只是一些说法
自定义button,我们只需要将子类继承 button

public class AnimationButton extends Button {

    public AnimationButton(Context context) {
        super(context);
        initFunction(context, null, 0);
    }
    public AnimationButton(Context context, AttributeSet attrs) {

        super(context, attrs);

        initFunction(context, attrs, 0);

    }

    public AnimationButton(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initFunction(context, attrs, defStyleAttr);

    }

    @Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        super.onSizeChanged(w, h, oldw, oldh);

    }

    //初始化操作方法
    private void initFunction(Context context, AttributeSet attrs, int defStyleAttr) {

    //获取自定义属性
        if (attrs != null) {
             TypedArray typedArray =context.obtainStyledAttributes(attrs,R.styleable.AnimationButton);         

        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
    //验证 drawable
    @Override
    protected boolean verifyDrawable(Drawable who) {
        return who == mDrawable || super.verifyDrawable(who);
    }


    //触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}

上述只是开发一个自定义View常用的思路

自定义 drawable


public class AnimationButtonDrawable extends Drawable {

    //默认 透明度
    private int mAlpha = 255;
    //默认画笔
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    //默认颜色
    private int mColor = 0;
    //绘制的区域
    private int mWidth, mHeight;
    //波纹圆形的 圆心与半径
    private float mCirculX, mCirculY, mCirculRadus;
    private Handler mHandler = new Handler(Looper.getMainLooper());



    private int mBackGroundNormalColor = Color.parseColor("#ffffff");
    //背景颜色
    private int mBackGroundColor = mBackGroundNormalColor;

    //背景矩形
    private RectF mBackGroundRect;
    private float rx, ry;

    //点击圆形颜色
    private int mAnimationCircleColor = Color.BLUE;
    //点击 按钮 down 颜色
    private int mBackGroundDownColor = Color.GRAY;



    public AnimationButtonDrawable() {
        //设置抗锯齿
        this.mPaint.setAntiAlias(true);
        //设置防抖动
        this.mPaint.setDither(true);
    }

    //绘制功能
    @Override
    public void draw(Canvas canvas) {

    }

    @Override
    public int getAlpha() {
        return mAlpha;
    }
    //设置透明度
    @Override
    public void setAlpha(int alpha) {
        //设置 drawable的透明度
        mAlpha = alpha;
        onColorOrAlphaChange();
    }

    //设置颜色滤镜
    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        if (mPaint.getColorFilter() != colorFilter) {
            mPaint.setColorFilter(colorFilter);
        }
    }

    //确认drawable是否有透明度
    @Override
    public int getOpacity() {
        int alpha = mPaint.getAlpha();
        if (alpha == 255) {
            //不透明
            return PixelFormat.OPAQUE;
        } else if (alpha == 0) {
            //全透明
            return PixelFormat.TRANSPARENT;
        } else {
            //半透明
            return PixelFormat.TRANSLUCENT;
        }
    }
    public void onColorOrAlphaChange() {
        mPaint.setColor(mColor);
        //获取画笔透明度
        if (mAlpha != 255) {
            int paintAlpha = mPaint.getAlpha();
            int realAppha = (int) (paintAlpha * (mAlpha / 255f));
            mPaint.setAlpha(realAppha);
        }
    }
}
  • 在这里,我们定义实现了一个基本的drawble AnimationButtonDrawable
  • 一个button ,要初始化使用的变量有

    有正常显示的背景颜色,
    有按下的背景颜色,
    当点击抬起时,绘制波纹的颜色,
    绘制波纹的位置与半径
  • 最重要的步骤是在draw方法中
    通过方法
    canvas.drawRoundRect(mBackGroundRect, rx, ry, mPaint);
    来绘制圆角矩形背景

    通过方法
    canvas.drawCircle(mCirculX, mCirculY, mCirculRadus, mPaint);
    来绘制点击后抬起的圆角矩形

    通过设置模式来解决边框圆角被覆盖问题
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));

    完整的draw方法

//绘制功能
@Override
public void draw(Canvas canvas) {

    //绘制区域
    int canvasWidth = canvas.getWidth();
    int canvasHeight = canvas.getHeight();
    //新建图层
    int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);
    mPaint.setColor(mBackGroundColor);

    //绘制背景 圆角矩形
    if (mBackGroundRect != null) {  
        canvas.drawRoundRect(mBackGroundRect, rx, ry, mPaint);
    }
    //设置图层重叠模式
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
    mPaint.setColor(mAnimationCircleColor);
    //绘制圆形波纹
    canvas.drawCircle(mCirculX, mCirculY, mCirculRadus, mPaint);
    //最后将画笔去除Xfermode
    mPaint.setXfermode(null);
    canvas.restoreToCount(layerId);
}

button 与 drawable结合

在button中,当button创建的时候,我们创建drawable,

mDrawable = new AnimationButtonDrawable();

然后在button的ondraw方法中,使用drawable的draw方法,这样就通过 canvas 画布将两者关联起来了

@Override
protected void onDraw(Canvas canvas) {
    mDrawable.draw(canvas);
    super.onDraw(canvas);
}

设置点击时的button背景颜色

在button中的onTouchEvent方法,监听事件的发生,并将事件传入到drawable中


@Override
public boolean onTouchEvent(MotionEvent event) {
    //设置事件
    mDrawable.setTouchEvent(event);
    return super.onTouchEvent(event);
}

在drawable中的setTouchEvent方法中进行事件处理


public void setTouchEvent(MotionEvent event) {
    //刷新
    invalidateSelf();
    //判断点击操作
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            onTouchDown(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_MOVE:
            onTouchMove(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_UP:
            onTouchUp(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_CANCEL:
            onTouchCancel(event.getX(), event.getY());
            break;
    }
}

在ontouchDown方法, 我们更新绘制圆角矩形的颜色为按下时的颜色,并在onTouchUp方法中恢复我们正常情况下显示的背景颜色,就可以达到button点击选择器的风格

在ontouchDown方法中,我们可以开启一个异步任务,在一定的时间内不断的绘制不同半径的圆 叠加在之前绘制好的矩形背景上面,就可以在视觉方面达到一种波纹效果,

在这里 绘制不大小的圆形,是通过 不断改变绘制半径来达到这个效果的

private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        invalidateSelf();
        if (mCirculRadus <= mWidth) {
            isRun = true;
            mCirculRadus += 18;
            mHandler.postDelayed(mRunnable, 2);
        } else {
            isRun = false;
            mCirculX = 0;
            mCirculY = 0;
            mCirculRadus = 0;
        }
    }
};

标签:水波纹,canvas,自定义,int,Button,private,event,mPaint,public
来源: https://blog.51cto.com/928343994/2841510

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有