Android點擊水波紋擴散效果整理(附帶一個自定義的水波紋效果控件)

 

很久很久沒有寫博客了,說來也有點慚愧。正好最近整理自己的項目工程目錄,看到一些值得分享的控件,準備在之後的幾篇博客中準備把它們陸續搬運上來。

 

這篇博客準備整理一下Android Material Design自帶的點擊水波紋擴散的效果。話不多說,開始正題。

水波紋效果分爲兩種:有界水波紋和無界水波紋。都通過系統自帶的動畫文件實現。

有界水波紋:

有界水波紋通過系統自帶的動畫文件 selectableItemBackground 實現只要將其設置爲控件的背景即可。簡單寫幾句代碼:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="?android:attr/selectableItemBackground"
    android:text="Button" />

效果如下:

無界水波紋:

無界水波紋通過動畫文件 selectableItemBackgroundBorderless 實現,用法和有界水波紋一樣,修改一下上面的代碼:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="?android:attr/selectableItemBackgroundBorderless"
    android:text="Button" />

效果:

可以看到,所謂的有界和無界的區別就在於,有界水波紋擴散不會超出控件自身的邊界,而無界水波紋擴散範圍是一個正方形區域,正方形的邊長取控件高寬的較大值。

當然這樣的效果還是太單調,有時我們需要自定義水波紋的顏色,方法也很簡單。

有界水波紋:
要自定義有界水波紋的顏色,只需要創建drawable文件,添加ripple節點,將節點的color屬性設置爲你想要的顏色,再在其下添加item節點,指定該item的id屬性爲mask即可。
比如說我們定義“button_red_mask”文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#FF5151">
    <item
        android:id="@android:id/mask"
        android:drawable="@color/colorPrimary" />
</ripple>

item節點中的drawable屬性另有用處,之後再講,但這裏並不影響水波紋的顏色,我這裏就隨便設了一個。之後再將這個文件設置爲控件的背景即可:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_mask"
    android:text="Button" />

看看效果:

無界水波紋:
無界水波紋要自定義波紋顏色就更簡單了,連上述的item節點都不需要,只需要ripple節點指定其color屬性即可。

定義“button_red_mask “文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#FF5151">

</ripple>

再將其設置爲控件的背景:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_unmask"
    android:text="Button" />

效果:

除了自定義波紋顏色,你甚至可以自定義波紋的擴散邊界。做法也不復雜,就是我們之前提到的item節點中的drawable屬性,只需要將drawable屬性設置爲指定的圖片,就可以將該圖片作爲擴散邊界。來試一試。

定義“button_red_mask_icon“文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#FF5151">
    <item
        android:id="@android:id/mask"
        android:drawable="@drawable/heart" />
</ripple>

將其設置爲控件的背景:

<Button
    android:id="@+id/button"
    android:layout_width="350dp"
    android:layout_height="350dp"
    android:layout_gravity="center_horizontal"
    android:background="@drawable/button_red_mask_icon"
    android:text="Button" />

看看效果:

當然自定義邊界所指定的圖片,除了真實的圖片,自定義的drawble資源也是可以的。

比如說我們先定義一個圓角矩形資源“button_red_up”

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#ff5151" />

    <corners android:radius="40dp" />

</shape>

再定義一個“button_red_mask_shape”文件,將item節點的drawable屬性設置爲上面的“button_red_up”:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#FF5151">
    <item
        android:id="@android:id/mask"
        android:drawable="@drawable/button_red_up" />
</ripple>

最後把它設置成控件的背景:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_mask_shape"
    android:text="Button" />

效果如下:

當然,上面的所有做法,控件的不點擊的時候是不顯示形狀的。有時候我們需要控件的不點擊的時候就顯示一個指定的形狀,那又該怎麼做呢?其實也不難,只需要在上述的item節點下,再添加一個shape節點來指定形狀即可。 

我們再定義一個“button_red_mask_shape_pro”文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#20000000">
    <item>
        <shape>
            <corners android:radius="40dp" />
            <solid android:color="#FF5151" />
        </shape>
    </item>
</ripple>

這個文件指定了控件形狀爲圓角矩形,水波紋顏色爲半透明的黑色。再把這個文件設置爲控件的背景:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_mask_shape_pro"
    android:text="Button" />

效果:

再進一步,如果還想給按鈕再加一個selector效果,即按鈕未按下時顯示一張圖,按下時顯示另一張圖,也是可以做到的。

先定義一個按鈕未按下時的資源“button_red_up”:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#ff5151" />

    <corners android:radius="40dp" />

</shape>

再定義一個按鈕按下時的資源“button_red_down”:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#BA3F3F" />

    <corners android:radius="40dp" />

</shape>

然後定義selector資源文件“button_red_mask_shape_selector”:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#20000000">
    <item>
        <selector>
            <item
                android:state_pressed="true"
                android:drawable="@drawable/button_red_down"/>
            <item
                android:state_pressed="false"
                android:drawable="@drawable/button_red_up"/>
        </selector>
    </item>
</ripple>

其實就是在item節點下再添加一個selector節點,引用之前定義的兩個資源即可。最後把控件的背景設置爲該資源:

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_mask_shape_selector"
    android:text="Button" />

來看看效果:

好了,以上就是Andorid的Material Design中自帶的水波紋擴散效果的所有內容了。

 

===========================================================

 

其實之前自己順手寫了一個點擊水波紋擴散效果的控件,雖然從來沒有用過,這裏也順便拿出來分享一下,沒準以後就用上了呢。

話不多說,先看效果:
 

實現的效果是點擊時生成一個隨手指移動的小圓圈,鬆開時小圓圈呈現水波紋擴散效果,之前在前端上經常看到這樣的設計。

所有代碼都被封裝在一個視圖類裏面,複製即可用。上源碼:

按鈕類 DiffusionButton.java
 

public class DiffusionButton extends AppCompatButton {

    private Context context;

    private Paint paint;
    private Path path;
    private RectF roundRect;

    private int width;
    private int height;
    private int touchX;
    private int touchY;
    private int maxRadius;
    private int currentRadius;
    private int invalidateInterval = 10;
    private boolean isPushButton;
    private boolean isClickFinish;
    private boolean isInit;

    /**
     * 可設置參數
     */
    // 擴散速度
    private int speed;

    // 擴散顏色
    private int diffusionColor;

    // 控件圓角半徑
    private int radius;

    // 控件左上角橫向半徑
    private int leftTopRadiusX;

    // 控件左上角縱向半徑
    private int leftTopRadiusY;

    // 控件右上角橫向半徑
    private int rightTopRadiusX;

    // 控件右上角縱向半徑
    private int rightTopRadiusY;

    // 控件左下角橫向半徑
    private int leftBottomRadiusX;

    // 控件左下角縱向半徑
    private int leftBottomRadiusY;

    // 控件右下角橫向半徑
    private int rightBottomRadiusX;

    // 控件右下角縱向半徑
    private int rightBottomRadiusY;

    // 按下時的圓圈半徑
    private int touchRadius;


    public DiffusionButton(Context context) {
        super(context, null);
    }

    public DiffusionButton(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.buttonStyle);
    }

    public DiffusionButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DiffusionButton);
        speed = array.getInt(R.styleable.DiffusionButton_speed, 25);
        diffusionColor = array.getColor(R.styleable.DiffusionButton_diffusionColor, Color.parseColor("#30000000"));
        radius = array.getDimensionPixelSize(R.styleable.DiffusionButton_radius, 0);
        leftTopRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftTopRadiusX, radius);
        leftTopRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftTopRadiusY, radius);
        leftBottomRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftBottomRadiusX, radius);
        leftBottomRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftBottomRadiusY, radius);
        rightTopRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightTopRadiusX, radius);
        rightTopRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightTopRadiusY, radius);
        rightBottomRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightBottomRadiusX, radius);
        rightBottomRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightBottomRadiusY, radius);
        touchRadius = array.getDimensionPixelSize(R.styleable.DiffusionButton_touchRadius, dp2px(20));

        array.recycle();

        init(context);
    }

    /**
     * 初始化方法
     *
     * @param context
     */
    private void init(Context context) {
        this.context = context;

        paint = new Paint();
        paint.setColor(diffusionColor);
        path = new Path();
    }

    /**
     * 構造剪裁路徑方法
     */
    private void buildPath() {

        if (path == null) {
            return;
        }

        path.reset();
        path.addRoundRect(roundRect, new float[]{
                leftTopRadiusX, leftTopRadiusY,
                rightTopRadiusX, rightTopRadiusY,
                rightBottomRadiusX, rightBottomRadiusY,
                leftBottomRadiusX, leftBottomRadiusY,
        }, Path.Direction.CCW);
    }

    /**
     * 擴散動畫完成後重置方法
     */
    private void resetData() {
        isPushButton = false;
        isClickFinish = false;
        currentRadius = touchRadius;

        invalidate();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        width = getMeasuredWidth();
        height = getMeasuredHeight();

        roundRect = new RectF(0, 0, width, height);

        buildPath();

        isInit = true;
    }

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

        if (!isPushButton && !isClickFinish) {
            return;
        }

        // 剪裁顯示區域
        canvas.clipPath(path);

        if (isClickFinish) {
            // 繪製擴散圓
            canvas.drawCircle(touchX, touchY, currentRadius, paint);

            if (currentRadius < maxRadius) {
                currentRadius += speed;

                postInvalidateDelayed(invalidateInterval);
            } else {
                resetData();
            }
        }

        if (isPushButton) {
            // 繪製點擊圓
            canvas.drawCircle(touchX, touchY, touchRadius, paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchX = (int) event.getX();
                touchY = (int) event.getY();

                isPushButton = true;

                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchX = (int) event.getX();
                touchY = (int) event.getY();

                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                if (touchX > 0 && touchY > 0 && touchX < width && touchY < height) {
                    isPushButton = false;
                    isClickFinish = true;
                    // 計算最大擴散半徑
                    maxRadius = (int) Math.max(Math.max(getDistance(touchX, touchY, 0, 0), getDistance(touchX, touchY, 0, height)),
                            Math.max(getDistance(touchX, touchY, width, 0), getDistance(touchX, touchY, width, height)));
                    currentRadius = touchRadius;

                    postInvalidateDelayed(invalidateInterval);
                } else {
                    resetData();
                }

                break;
        }

        return super.onTouchEvent(event);
    }

    private double getDistance(int x1, int y1, int x2, int y2) {

        return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    }

    /**
     * 設置擴散速度
     *
     * @param speed
     */
    public void setSpeed(int speed) {
        this.speed = speed;
    }

    /**
     * 設置擴散顏色
     *
     * @param diffusionColor
     */
    public void setDiffusionColor(int diffusionColor) {
        this.diffusionColor = diffusionColor;
        if (paint != null) {
            paint.setColor(diffusionColor);
        }
    }

    /**
     * 設置控件圓角半徑
     *
     * @param radius 半徑,單位dp
     */
    public void setRadius(int radius) {
        if (radius >= 0) {
            this.radius = dp2px(radius);

            leftTopRadiusX = radius;
            leftTopRadiusY = radius;
            rightTopRadiusX = radius;
            rightTopRadiusY = radius;
            leftBottomRadiusX = radius;
            leftBottomRadiusY = radius;
            rightBottomRadiusX = radius;
            rightBottomRadiusY = radius;

            if (isInit) {
                buildPath();
            }
        }
    }

    /**
     * 設置控件圓角半徑
     * <p>
     * 參數爲四個數組,分別對應控件左上角橫縱向半徑、右上角橫縱向半徑、左下角橫縱向半徑、右下角橫縱向半徑
     *
     * @param leftTopRadius     半徑,單位dp,下同
     * @param rightTopRadius
     * @param leftBottomRadius
     * @param rightBottomRadius
     */
    public void setRadius(int[] leftTopRadius, int[] rightTopRadius, int[] leftBottomRadius, int[] rightBottomRadius) {
        leftTopRadiusX = dp2px(leftTopRadius[0]);
        leftTopRadiusY = dp2px(leftTopRadius[1]);
        rightTopRadiusX = dp2px(rightTopRadius[0]);
        rightTopRadiusY = dp2px(rightTopRadius[1]);
        leftBottomRadiusX = dp2px(leftBottomRadius[0]);
        leftBottomRadiusY = dp2px(leftBottomRadius[1]);
        rightBottomRadiusX = dp2px(rightBottomRadius[0]);
        rightBottomRadiusY = dp2px(rightBottomRadius[1]);

        if (isInit) {
            buildPath();
        }
    }

    /**
     * 設置按下時的圓圈半徑
     *
     * @param touchRadius 半徑,單位dp
     */
    public void setTouchRadius(int touchRadius) {
        this.touchRadius = dp2px(touchRadius);
    }

    private int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
    }
}

佈局類 DiffusionLayout.java

public class DiffusionLayout extends LinearLayout {

    private Context context;

    private Paint paint;
    private Path path;
    private RectF roundRect;

    private int width;
    private int height;
    private int touchX;
    private int touchY;
    private int maxRadius;
    private int currentRadius;
    private int invalidateInterval = 10;
    private boolean isPushButton;
    private boolean isClickFinish;
    private boolean isInit;


    /**
     * 可設置參數
     */
    // 擴散速度
    private int speed;

    // 擴散顏色
    private int diffusionColor;

    // 控件圓角半徑
    private int radius;

    // 控件左上角橫向半徑
    private int leftTopRadiusX;

    // 控件左上角縱向半徑
    private int leftTopRadiusY;

    // 控件右上角橫向半徑
    private int rightTopRadiusX;

    // 控件右上角縱向半徑
    private int rightTopRadiusY;

    // 控件左下角橫向半徑
    private int leftBottomRadiusX;

    // 控件左下角縱向半徑
    private int leftBottomRadiusY;

    // 控件右下角橫向半徑
    private int rightBottomRadiusX;

    // 控件右下角縱向半徑
    private int rightBottomRadiusY;

    // 按下時的圓圈半徑
    private int touchRadius;


    public DiffusionLayout(Context context) {
        this(context, null);
    }

    public DiffusionLayout(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public DiffusionLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DiffusionLayout);
        speed = array.getInt(R.styleable.DiffusionButton_speed, 25);
        diffusionColor = array.getColor(R.styleable.DiffusionButton_diffusionColor, Color.parseColor("#30000000"));
        radius = array.getDimensionPixelSize(R.styleable.DiffusionButton_radius, 0);
        leftTopRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftTopRadiusX, radius);
        leftTopRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftTopRadiusY, radius);
        leftBottomRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftBottomRadiusX, radius);
        leftBottomRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_leftBottomRadiusY, radius);
        rightTopRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightTopRadiusX, radius);
        rightTopRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightTopRadiusY, radius);
        rightBottomRadiusX = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightBottomRadiusX, radius);
        rightBottomRadiusY = array.getDimensionPixelSize(R.styleable.DiffusionButton_rightBottomRadiusY, radius);
        touchRadius = array.getDimensionPixelSize(R.styleable.DiffusionButton_touchRadius, dp2px(20));

        array.recycle();

        init(context);
    }

    /**
     * 初始化方法
     *
     * @param context
     */
    private void init(Context context) {
        this.context = context;

        paint = new Paint();
        paint.setColor(diffusionColor);
        path = new Path();
        setWillNotDraw(false);
        setClickable(true);
    }

    /**
     * 構造剪裁路徑方法
     */
    private void buildPath() {

        if (path == null) {
            return;
        }

        path.reset();
        path.addRoundRect(roundRect, new float[]{
                leftTopRadiusX, leftTopRadiusY,
                rightTopRadiusX, rightTopRadiusY,
                rightBottomRadiusX, rightBottomRadiusY,
                leftBottomRadiusX, leftBottomRadiusY,
        }, Path.Direction.CCW);
    }

    /**
     * 擴散動畫完成後重置方法
     */
    private void resetData() {
        isPushButton = false;
        isClickFinish = false;
        currentRadius = touchRadius;

        invalidate();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        width = getMeasuredWidth();
        height = getMeasuredHeight();

        roundRect = new RectF(0, 0, width, height);

        buildPath();

        isInit = true;
    }

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

        if (!isPushButton && !isClickFinish) {
            return;
        }

        // 剪裁顯示區域
        canvas.clipPath(path);

        if (isClickFinish) {
            // 繪製擴散圓
            canvas.drawCircle(touchX, touchY, currentRadius, paint);

            if (currentRadius < maxRadius) {
                currentRadius += speed;

                postInvalidateDelayed(invalidateInterval);
            } else {
                resetData();
            }
        }

        if (isPushButton) {
            // 繪製點擊圓
            canvas.drawCircle(touchX, touchY, touchRadius, paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchX = (int) event.getX();
                touchY = (int) event.getY();

                isPushButton = true;

                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchX = (int) event.getX();
                touchY = (int) event.getY();

                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                if (touchX > 0 && touchY > 0 && touchX < width && touchY < height) {
                    isPushButton = false;
                    isClickFinish = true;
                    // 計算最大擴散半徑
                    maxRadius = (int) Math.max(Math.max(getDistance(touchX, touchY, 0, 0), getDistance(touchX, touchY, 0, height)),
                            Math.max(getDistance(touchX, touchY, width, 0), getDistance(touchX, touchY, width, height)));
                    currentRadius = touchRadius;

                    postInvalidateDelayed(invalidateInterval);
                } else {
                    resetData();
                }

                break;
        }

        return super.onTouchEvent(event);
    }

    private double getDistance(int x1, int y1, int x2, int y2) {

        return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    }

    /**
     * 設置擴散速度
     *
     * @param speed
     */
    public void setSpeed(int speed) {
        this.speed = speed;
    }

    /**
     * 設置擴散顏色
     *
     * @param diffusionColor
     */
    public void setDiffusionColor(int diffusionColor) {
        this.diffusionColor = diffusionColor;
        if (paint != null) {
            paint.setColor(diffusionColor);
        }
    }

    /**
     * 設置控件圓角半徑
     *
     * @param radius 半徑,單位dp
     */
    public void setRadius(int radius) {
        if (radius >= 0) {
            this.radius = dp2px(radius);

            leftTopRadiusX = radius;
            leftTopRadiusY = radius;
            rightTopRadiusX = radius;
            rightTopRadiusY = radius;
            leftBottomRadiusX = radius;
            leftBottomRadiusY = radius;
            rightBottomRadiusX = radius;
            rightBottomRadiusY = radius;

            if (isInit) {
                buildPath();
            }
        }
    }

    /**
     * 設置控件圓角半徑
     * <p>
     * 參數爲四個數組,分別對應控件左上角橫縱向半徑、右上角橫縱向半徑、左下角橫縱向半徑、右下角橫縱向半徑
     *
     * @param leftTopRadius     半徑,單位dp,下同
     * @param rightTopRadius
     * @param leftBottomRadius
     * @param rightBottomRadius
     */
    public void setRadius(int[] leftTopRadius, int[] rightTopRadius, int[] leftBottomRadius, int[] rightBottomRadius) {
        leftTopRadiusX = dp2px(leftTopRadius[0]);
        leftTopRadiusY = dp2px(leftTopRadius[1]);
        rightTopRadiusX = dp2px(rightTopRadius[0]);
        rightTopRadiusY = dp2px(rightTopRadius[1]);
        leftBottomRadiusX = dp2px(leftBottomRadius[0]);
        leftBottomRadiusY = dp2px(leftBottomRadius[1]);
        rightBottomRadiusX = dp2px(rightBottomRadius[0]);
        rightBottomRadiusY = dp2px(rightBottomRadius[1]);

        if (isInit) {
            buildPath();
        }
    }

    /**
     * 設置按下時的圓圈半徑
     *
     * @param touchRadius 半徑,單位dp
     */
    public void setTouchRadius(int touchRadius) {
        this.touchRadius = dp2px(touchRadius);
    }

    private int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
    }
}

控件有兩個,DiffusionButton和DiffusionLayout,分別應對點擊按鈕和點擊佈局的使用場景。DiffusionButton繼承自Button,DiffusionLayout繼承自LinearLayout,像使用普通的Button和Layout來使用它們就可以了。

像下面這樣:

<com.min.diffusionbutton.view.DiffusionButton
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_up"
    android:text="Button"
    android:textColor="#ffffff"
    android:textSize="16dp"
    app:radius="25dp" />

<com.min.diffusionbutton.view.DiffusionLayout
    android:id="@+id/layout"
    android:layout_width="350dp"
    android:layout_height="350dp"
    android:layout_margin="15dp"
    android:background="@drawable/button_red_up"
    app:radius="40dp"
    app:touchRadius="40dp" />

運行一下就能看到開頭的效果了。

當然控件還支持一些自定義屬性設置,各個屬性的意義在源碼註釋裏已經寫的很清楚了,這裏不再贅述。


最後附上源碼地址:https://download.csdn.net/download/Sure_Min/12565978

 

這次的內容就到這裏,我們下次再見。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章