Ripple Android L预览触控

时间:2014-07-21 09:33:47

标签: java android android-view ontouchevent 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(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类不能正常工作..那就是创建一些只在按钮中影响整个视图?

3 个答案:

答案 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(预览)当前具有的相同动画。使用这个类:

  • 创建自定义视图。 (在gist示例中,我创建了一个LinearLayout)
  • 初始化TouchEffectAnimator对象。
  • 定义它的一些属性,如颜色,效果类型,持续时间和剪裁边角尺寸。
  • 视图的onTouchEvent 中调用TouchEffectAnimator的 onTouchEvent 方法。
  • 视图的onDraw 中调用TouchEffectAnimator的 onDraw 方法。

就是这样。但是要使这个类正常工作,应该做两件事。

  • 视图上应该有一些 OnClickListener 来获取UP touch事件。
  • 应该为视图设置自定义或透明背景。如果没有设置为背景,则不显示动画。

我希望它也适合你。

P.S。我为我的库项目Android FlatUI Kit创建了这个类。你也可以在FlatButton类中看到这个类的用法。

答案 2 :(得分:0)

您可以使用此库,以获得'涟漪效应',支持旧设备,api版本> = 14,一些黑客也可以支持api版本< 14。

链接:material-ripple

这是一个使用示例:

  1. 包含感兴趣的观点:

    <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>
    
  2. 定义样式

    <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>