Java Ripple Android L预览触摸屏

Java Ripple Android L预览触摸屏,java,android,android-view,touch-event,android-5.0-lollipop,Java,Android,Android View,Touch Event,Android 5.0 Lollipop,我试图在一个视图中创建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

我试图在一个视图中创建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预览版不完全一样,但它仍然有效。。但是..如果我更改
按钮
并尝试使用
视图
类,则该类不起作用..这就是在整个视图中,而仅在按钮中创建该效果的原因吗

您需要从onTouchEvent()返回true才能继续接收事件。按钮之所以这样做是因为它是用来处理点击事件的,而默认视图则不是

如果您将视图设置为可单击,您将获得预期的行为。如果查看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;
}

您需要从onTouchEvent()返回true才能继续接收事件。按钮之所以这样做是因为它是用来处理点击事件的,而默认视图则不是

如果您将视图设置为可单击,您将获得预期的行为。如果查看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;
}

您需要从onTouchEvent()返回true才能继续接收事件。按钮之所以这样做是因为它是用来处理点击事件的,而默认视图则不是

如果您将视图设置为可单击,您将获得预期的行为。如果查看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;
}

您需要从onTouchEvent()返回true才能继续接收事件。按钮之所以这样做是因为它是用来处理点击事件的,而默认视图则不是

如果您将视图设置为可单击,您将获得预期的行为。如果查看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;
}

我的回答有点晚了,我也分享了这个解决方案,但我也想在这里分享。我用Niek Haarman的思想创建了另一个名为TouchEffectAnimator的类。顺便说一下,多亏了哈曼先生

您可以看到该类及其示例用法。我也会简单地解释一下

该类包含所有必需的方法和变量,并创建与AndroidL(preview)当前具有的动画相同的动画。要使用此类,请执行以下操作:

  • 创建自定义视图。(在示例中,我创建了一个LinearLayout)
  • 初始化TouchEffector Animator对象
  • 定义它的一些属性,如颜色、效果类型、持续时间和剪辑角大小
  • 视图的onTouchEvent中调用TouchEffectAnimator的onTouchEvent方法
  • 视图的onDraw中调用TouchEffectAnimator的onDraw方法
就这样。但是为了让这个类正常工作,应该做两件事

  • 视图上应该有一些OnClickListener,以获取UP touch事件
  • 应该为视图设置自定义或透明背景。如果未将任何内容设置为背景,则不会显示动画
我希望它对你也有用


另外,我为我的图书馆项目创建了这个类。你也可以在FlatButton类中看到这个类的用法。

我的答案有点晚,我也分享了这个解决方案,但我也想在这里分享。我用Niek Haarman的思想创建了另一个名为TouchEffectAnimator的类。顺便说一下,多亏了哈曼先生

您可以看到该类及其示例用法。我也会简单地解释一下

该类包含所有必需的方法和变量,并创建与AndroidL(preview)当前具有的动画相同的动画。要使用此类,请执行以下操作:

  • 创建自定义视图。(在示例中,我创建了一个LinearLayout)
  • 初始化TouchEffector Animator对象
  • 定义它的一些属性,如颜色、效果类型、持续时间和剪辑角大小
  • 视图的onTouchEvent中调用TouchEffectAnimator的onTouchEvent方法
  • 视图的onDraw中调用TouchEffectAnimator的onDraw方法
就这样。但是为了让这个类正常工作,应该做两件事

  • 视图上应该有一些OnClickListener,以获取UP touch事件
  • 应该为视图设置自定义或透明背景。如果未将任何内容设置为背景,则不会显示动画
我希望它对你也有用


另外,我为我的图书馆项目创建了这个类。你也可以在FlatButton类中看到这个类的用法。

我的答案有点晚,我也分享了这个解决方案,但我也想在这里分享。我用Niek Haarman的思想创建了另一个名为TouchEffectAnimator的类。顺便说一下,多亏了哈曼先生

您可以看到该类及其示例用法。我也会简单地解释一下

该类包含所有必需的方法和变量,并创建与AndroidL(preview)当前具有的动画相同的动画。要使用此类,请执行以下操作: