我正在制作一个自定义按钮视图,它具有渐变边框,圆角和透明背景。我将按钮的背景设置为由以下代码生成的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做什么?
我的按钮如下所示:
我真正想要实现的目标
以编程方式创建一个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而没有任何连锁反应。
答案 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.selectableItemBackground
或StateListDrawable
,它会为您的按钮提供旧平台版本的基本“按下”背景。