我需要做一些类似 Listview
项目背景变化的链式 react 。我尝试像这样使用 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
,但这对应用程序来说太难了,而且可能会有一些滞后。
最佳答案
你可以用自定义 View 来做,在onDraw()中实现循环过渡,但是很复杂。
您可以通过在 subview 上使用 ViewAnimationUtils.createCircularReveal()
来解决复杂性。但缺点是它仅适用于 API 21+。
简而言之,单元格的根布局必须是 FrameLayout
或 RelativeLayout
。
当过渡开始时,您使用开始和结束颜色在您的单元格下动态添加 2 个 View ,然后在 2 个之间使用圆形显示进行过渡。在过渡结束时,您只需删除 2 个 subview 以保持 View 层次结构更干净一些。
结果如下:
在代码中:
单元格布局:
<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();
}
关于android - 无需触摸的涟漪效果动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32353435/