在透明自定义按钮视图上获得涟漪效果

时间:2017-01-09 20:06:45

标签: android android-view android-drawable rippledrawable

我正在制作一个自定义按钮视图,它具有渐变边框,圆角和透明背景。我将按钮的背景设置为由以下代码生成的drawable:

protected Drawable getBackgroundDrawable() {
    GradientDrawable backgroundDrawable = new GradientDrawable(
            mOrientation,
            mGradientColors);
    backgroundDrawable.setCornerRadius(getHeight() / 2);
    backgroundDrawable.setShape(GradientDrawable.RECTANGLE);

    if (!mFilled) {
        Bitmap background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas backgroundCanvas = new Canvas(background);
        backgroundCanvas.drawARGB(0, 0, 0, 0);
        backgroundDrawable.setBounds(0, 0, getWidth(), getHeight());
        backgroundDrawable.draw(backgroundCanvas);

        Paint rectPaint = new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        backgroundCanvas.drawRoundRect(new RectF(mStroke, mStroke,
                        getWidth() - mStroke,
                        getHeight() - mStroke),
                getHeight() / 2,
                getHeight() / 2,
                rectPaint);

        return new BitmapDrawable(getResources(), background);
    } else {
        return backgroundDrawable;
    }
}

唯一的问题是,当您现在点击该按钮时,您没有任何反馈。当我已经使用生成的drawable作为背景时,如何在按钮背面添加涟漪效果?我是否必须使用LayerDrawable做什么?

我的按钮如下所示:

enter image description here

我真正想要实现的目标

以编程方式创建一个Drawable,其结果与此XML drawable相同,其中ripple元素中的项目是我在上图中生成的Drawable:

<ripple android:color="@android:color/black" xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/background"></item>
</ripple>

我尝试了什么

我现在尝试将RippleDrawable与GradientDrawable结合使用,以在代码中重新创建上面的XML。很简单,我想:

GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.TRANSPARENT);
gradientDrawable.setStroke(mStroke, Color.GREEN);
gradientDrawable.setCornerRadius(getHeight() / 2);

ColorStateList rippleStateList = ColorStateList.valueOf(Color.BLUE);
return new RippleDrawable(rippleStateList, gradientDrawable, gradientDrawable);

这将返回一个带绿色笔划的简单drawable。但是,当您单击它时,没有任何反应。与XML不同,您可以清楚地看到边界上的涟漪效应。当我将第三个参数设置为null时,效果相同。当我只将第二个参数设置为null时,它只返回一个空的transparant drawable而没有任何连锁反应。

1 个答案:

答案 0 :(得分:2)

您应该使用RippleDrawable作为自定义按钮的背景。 RippleDrawable有一个遮罩层,这正是您要寻找的。要以编程方式执行此操作,您可以像这样创建RippleDrawable

float[] outerRadii = new float[8];
Arrays.fill(outerRadii, height / 2);

RoundRectShape shape = new RoundRectShape(outerRadii, null, null);
ShapeDrawable mask = new ShapeDrawable(shape);

ColorStateList stateList = ColorStateList.valueof(ContextCompat.getColor(getContext(), R.color.ripple));

setBackground(new RippleDrawable(stateList, getBackgroundDrawable(), mask);

请注意,RippleDrawable仅适用于API级别21+,因此如果您希望同时支持旧版本,则需要回归其他内容;可能是android.R.attr.selectableItemBackgroundStateListDrawable,它会为您的按钮提供旧平台版本的基本“按下”背景。