【问题标题】:Make ripple fill whole View使波纹填充整个视图
【发布时间】:2018-06-10 13:49:43
【问题描述】:

在我的应用程序中,我想创建一个填充整个视图的波纹。因为它不能正常工作,所以我创建了一个最小的示例应用程序并在那里进行了尝试,但没有成功。

我的布局如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent" android:padding="16dp">

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/ripple"
        android:onClick="onViewClicked" />

</LinearLayout>

我的drawable是这样定义的:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#1E88E5"
    android:radius="0dp">

    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white" />

</ripple>

Here 是一个视频,它现在的样子。我希望这个圆圈(我认为它正式称为热点)从 middel 开始增长,直到它填满整个 View。我不是在谈论有意识地设置为 0dp 的波纹半径。你有什么想法我可以做到这一点吗?

编辑:最后我想实现类似this

对于不想阅读所有答案的每个人:我设法实现它并为此创建了一个repo。随意在您的项目中使用它并向我发送拉取请求。

【问题讨论】:

  • 您在实际的 REAL 测试设备上有哪些 API?不幸的是,我认为它(RippleDrawable)仅适用于 API 21+(Android 5.0,LOLLIPOP)。支持库 21 仍然无法在旧设备上运行。
  • 是的,你是对的。我在 API 26 Oreo 上对其进行了测试。如果真正的解决方案适用于 API 14+,那就太好了
  • 我想我见过一个可以做到这一点的库,如果我找到了,请回复你。
  • @Cilenco 尝试使用这个 android:background="?android:attr/selectableItemBackground"。如果你对库没问题,请查看android-arsenal.com/tag/167
  • github.com/traex/RippleEffect 库是我测试过的最好的。易于实施和 API 14 +。

标签: android android-drawable android-resources ripple rippledrawable


【解决方案1】:

您可以通过创建自定义 RippleView 来实现此效果。使用onDraw 方法在全视图上绘制圆圈并将动画设置为该圆圈。

if (animationRunning) {
            canvas.save();
            if (rippleDuration <= timer * frameRate) {
                animationRunning = false;
                timer = 0;
                durationEmpty = -1;
                timerEmpty = 0;
                // There is problem on Android M where canvas.restore() seems to be called automatically
                // For now, don't call canvas.restore() manually on Android M (API 23)
                if(Build.VERSION.SDK_INT != 23) {
                    canvas.restore();
                }
                invalidate();
                if (onCompletionListener != null) onCompletionListener.onComplete(this);
                return;
            } else
                canvasHandler.postDelayed(runnable, frameRate);

            if (timer == 0)
                canvas.save();


            canvas.drawCircle(x, y, (radiusMax * (((float) timer * frameRate) / rippleDuration)), paint);

            paint.setColor(Color.parseColor("#ffff4444"));

            if (rippleType == 1 && originBitmap != null && (((float) timer * frameRate) / rippleDuration) > 0.4f) {
                if (durationEmpty == -1)
                    durationEmpty = rippleDuration - timer * frameRate;

                timerEmpty++;
                final Bitmap tmpBitmap = getCircleBitmap((int) ((radiusMax) * (((float) timerEmpty * frameRate) / (durationEmpty))));
                canvas.drawBitmap(tmpBitmap, 0, 0, paint);
                tmpBitmap.recycle();
            }

            paint.setColor(rippleColor);

            if (rippleType == 1) {
                if ((((float) timer * frameRate) / rippleDuration) > 0.6f)
                    paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timerEmpty * frameRate) / (durationEmpty)))));
                else
                    paint.setAlpha(rippleAlpha);
            }
            else
                paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timer * frameRate) / rippleDuration))));

            timer++;
        }

该实现是从RippleEffect Library 项目中窃取的。在库项目中找到完整的实现。

要仅从中心位置创建圆,请使用以下方法

 /**
     * Launch Ripple animation for the current view centered at x and y position
     *
     * @param x Horizontal position of the ripple center
     * @param y Vertical position of the ripple center
     */
    public void animateRipple(final float x, final float y) {
        createAnimation(x, y);
    }



/**
 * Create Ripple animation centered at x, y
 *
 * @param x Horizontal position of the ripple center
 * @param y Vertical position of the ripple center
 */
private void createAnimation(final float x, final float y) {
    if (this.isEnabled() && !animationRunning) {
        if (hasToZoom)
            this.startAnimation(scaleAnimation);

        radiusMax = Math.max(WIDTH, HEIGHT);

        if (rippleType != 2)
            radiusMax /= 2;

        radiusMax -= ripplePadding;

        if (isCentered || rippleType == 1) {
            this.x = getMeasuredWidth() / 2;
            this.y = getMeasuredHeight() / 2;
        } else {
            this.x = x;
            this.y = y;
        }

        animationRunning = true;

        if (rippleType == 1 && originBitmap == null)
            originBitmap = getDrawingCache(true);

        invalidate();
    }
}

输出:

你可以得到一个从中间增长直到填满整个视图的圆圈

【讨论】:

  • 感谢您的出色回答。我设法自己实现了这一点,并为它创建了一个repo。我使用了 API 11 中的 Animation 类,并没有像在库中那样自行计算所有内容,因此请自行决定哪个版本最适合您。
【解决方案2】:

可点击视图的涟漪效应

常规按钮的波纹效果在 API 21 中默认会起作用,而对于其他
可触摸视图,可以通过指定来实现
android:background="?android:attr/selectableItemBackground"> 在 Java 代码中 int[] attrs = new int[]{R.attr.selectableItemBackground}; TypedArray typedArray = getActivity().obtainStyledAttributes(attrs); int backgroundResource = typedArray.getResourceId(0, 0); myView.setBackgroundResource(backgroundResource);

按钮

大多数按钮都是由几个drawables组成的。通常,您会拥有如下所示的压缩版和
正常版资产: /drawable/button.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>
    <item android:drawable="@drawable/button_normal"/>
</selector>
如果您有一个具有选定状态的自定义按钮,您的文本颜色会根据状态等更改
。因此,默认按钮背景不会
在此处为您工作。您可以为自己的可绘制对象和
自定义按钮添加此反馈,只需将它们包装在波纹元素中即可: /drawable-v21/button.xml:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item android:drawable="@drawable/button_normal" />
</ripple>

使用?android:colorControlHighlight 将使波纹的颜色与您应用中的内置波纹颜色相同。

如果您不喜欢默认的灰色,您可以指定您希望android:colorControlHighlight 在您的主题中使用的颜色。

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    <item name="android:colorControlHighlight">@color/your_custom_color</item>
  </style>

</resources>

如果您希望波纹延伸到视图边界之外,则可以
改为使用?attr/selectableItemBackgroundBorderless。这适用于作为较大视图一部分的
ImageButtons 和较小的 Buttons:

【讨论】:

    【解决方案3】:

    试试这个,希望对你有用

    使用android:foreground="@drawable/ripple"

    而不是 android:background="@drawable/ripple"

    并将android:radius="0dp" 更改为 50dp 或 100dp 并检查

    【讨论】:

      猜你喜欢
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多