不触摸的情况下实现水波纹效果动画

4

我需要做一些像水波纹效果的Listview项目背景变化。我尝试使用如下方法:ObjectAnimator

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(activity,
                    R.animator.animator_bkg);
            set.setTarget(childLinear);
            set.setInterpolator(new AccelerateInterpolator());
            set.start(); 

R.animator.animator_bkg:

<objectAnimator
   android:propertyName="backgroundColor"
   android:duration="3000"
   android:valueFrom="@color/white"
   android:valueTo="@color/redTrans"
   android:repeatCount="-1"
   android:repeatMode="reverse"/>

它可以流畅地更改背景(完全填充),但我需要像点击按钮后的涟漪效果一样逐渐填充ListView项目。

我认为,也许我可以使用 Canvas 覆盖 onDraw,但这对应用程序来说太难了,并且可能会有一些卡顿。


这将自动适用于棒棒糖设备,不是吗? - Kaveesh Kanwal
这也适用于早期版本的设备。 - Александр Шевчук
1个回答

2
你可以使用自定义视图并在onDraw()中实现圆形过渡,但这很复杂。
你可以通过在子视图上使用ViewAnimationUtils.createCircularReveal()来解决复杂性。但缺点是它只适用于API 21+。
简而言之,单元格的根布局必须是FrameLayout或RelativeLayout。 当转换开始时,您动态添加两个视图到单元格下面,一个是起始颜色,一个是结束颜色,然后使用圆形揭示之间的转换。在转换结束时,您只需删除2个子视图即可使视图层次结构更加清晰。
这是结果:

Color reveal

在代码中:
单元格布局:
<FrameLayout
    android:id="@+id/cell_root"
    android:layout_width="match_parent"
    android:layout_height="72dp">

    <LinearLayout
        android:id="@+id/cell_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:background="#FF00FF">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Title"
            android:textSize="18sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="This is content"
            android:textSize="14sp" />
    </LinearLayout>

</FrameLayout>

触发背景转换的代码:
private void changeBackgroundColor() {
    final FrameLayout startingColorFrame = new FrameLayout(mCellRoot.getContext());
    final FrameLayout endingColorFrame = new FrameLayout(mCellRoot.getContext());
    startingColorFrame.setBackground(mCellContent.getBackground());
    endingColorFrame.setBackground(mPendingColor);
    mCellContent.setBackground(null);
    endingColorFrame.setVisibility(View.GONE);
    mCellRoot.addView(endingColorFrame, 0, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    mCellRoot.addView(startingColorFrame, 0, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

    int finalRadius = (int) Math.sqrt(mCellRoot.getWidth()*mCellRoot.getWidth() + mCellRoot.getHeight()*mCellRoot.getHeight());
    final int sourceX = mCellRoot.getWidth() / 3;
    final int sourceY = mCellRoot.getHeight() / 2;
    // this is API 21 minimum. Add proper checks
    final Animator circularReveal = ViewAnimationUtils.createCircularReveal(endingColorFrame, sourceX, sourceY, 0, finalRadius);
    endingColorFrame.setVisibility(View.VISIBLE);
    circularReveal.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(final Animator animation) {
            super.onAnimationEnd(animation);
            mStartButton.setEnabled(true);
            mCellContent.setBackground(mPendingColor);
            mPendingColor = startingColorFrame.getBackground();
            mCellRoot.removeView(startingColorFrame);
            mCellRoot.removeView(endingColorFrame);
        }
    });
    // customize the animation here
    circularReveal.setDuration(800);
    circularReveal.setInterpolator(new AccelerateInterpolator());
    circularReveal.start();
}

然后在Canvas中重新实现揭示效果,这是唯一的方法。对于Lollipop之前的版本,您可以使用动画器和ArgbEvaluator来实现平滑的颜色过渡。 - pdegand59
或者使用类似 https://github.com/ozodrukh/CircularReveal 的社区兼容版本的 Circular Reveal。 - pdegand59

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接