我试图创建Android L预览"涟漪"视图中对触摸事件的影响。如果我使用此代码按钮工作:
public class MyButton extends Button {
private float mDownX;
private float mDownY;
private float mRadius;
private Paint mPaint;
public MyButton(final Context context) {
super(context);
init();
}
public MyButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public MyButton(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAlpha(100);
}
@Override
public boolean onTouchEvent(@NonNull final MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
mDownX = event.getX();
mDownY = event.getY();
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "radius", 0, getWidth() * 3.0f);
animator.setInterpolator(new AccelerateInterpolator());
animator.setDuration(400);
animator.start();
}
return super.onTouchEvent(event);
}
public void setRadius(final float radius) {
mRadius = radius;
if (mRadius > 0) {
RadialGradient radialGradient = new RadialGradient(
mDownX,
mDownY,
mRadius * 3,
Color.TRANSPARENT,
Color.BLACK,
Shader.TileMode.MIRROR
);
mPaint.setShader(radialGradient);
}
invalidate();
}
private Path mPath = new Path();
private Path mPath2 = new Path();
@Override
protected void onDraw(@NonNull final Canvas canvas) {
super.onDraw(canvas);
mPath2.reset();
mPath2.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW);
canvas.clipPath(mPath2);
mPath.reset();
mPath.addCircle(mDownX, mDownY, mRadius / 3, Path.Direction.CW);
canvas.clipPath(mPath, Region.Op.DIFFERENCE);
canvas.drawCircle(mDownX, mDownY, mRadius, mPaint);
}
}
即使不完全像在Android L预览中那样但它仍然有效..但是..如果我更改Button
并且我尝试使用View
类不能正常工作..那就是创建一些只在按钮中影响整个视图?
答案 0 :(得分:2)
您需要从onTouchEvent()返回true以继续接收事件。按钮执行此操作是因为它用于处理单击事件,而默认视图不用。
如果您将View设置为可点击,您将获得预期的行为。如果你看一下L-preview中的纹波,你会发现它只出现在启用和可点击的视图上。
private void init() {
mPaint = new Paint();
mPaint.setAlpha(100);
setClickable(true);
setFocusable(true);
}
或者,你可以随时调用super然后返回true:
@Override
public boolean onTouchEvent(@NonNull final MotionEvent event) {
...
super.onTouchEvent(event);
return true;
}
答案 1 :(得分:1)
我的回答有点迟了,我也分享了这个解决方案on this original question,但我也想在这里分享。我用Niek Haarman的想法创建了另一个名为TouchEffectAnimator的类。顺便感谢哈尔曼先生。
您可以看到该类及其示例用法on this gist。我也会简单地解释一下。
该类包含其中的所有必要方法和变量,并创建与Android L(预览)当前具有的相同动画。使用这个类:
就是这样。但是要使这个类正常工作,应该做两件事。
我希望它也适合你。
P.S。我为我的库项目Android FlatUI Kit创建了这个类。你也可以在FlatButton类中看到这个类的用法。
答案 2 :(得分:0)
您可以使用此库,以获得'涟漪效应',支持旧设备,api版本> = 14,一些黑客也可以支持api版本< 14。
这是一个使用示例:
包含感兴趣的观点:
<com.balysv.materialripple.MaterialRippleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/MyStyleViewContainer">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- content -->
</android.support.v7.widget.CardView>
</com.balysv.materialripple.MaterialRippleLayout>
定义样式
<style name="base_ripple_style" parent="AppTheme">
<item name="mrl_rippleAlpha">0.3</item>
<item name="mrl_rippleDelayClick">true</item>
<item name="mrl_rippleDuration">300</item>
<item name="mrl_rippleFadeDuration">50</item>
<item name="mrl_rippleOverlay">true</item>
<item name="mrl_rippleRoundedCorners">5dp</item>
</style>
<style name="MyStyleViewContainer" parent="base_ripple_style">
<item name="mrl_rippleColor">@android:color/white</item>
</style>