android - 如何在拖动视图时使用旋转动画以使中心位置不断变化?解决从度到度的问题
问题描述
在我的回收站视图中,我希望当用户拿着一个项目并移动它时,所有项目都可以摇晃/摆动/摆动。我面临的问题是,当用户持有该项目并将其移动到相同的视图类型中时,摆动是可以的,但是当有人将它拖到 recyclerview 的顶部时(这是在 recyclerview 中创建为视图类型的标题)摆动增加了很多。
在玩弄这些值时,我意识到这是因为即使旋转角度相同,它离项目中心越远,旋转就会增加。
我也尝试使用对象动画师来执行此操作,但它没有帮助,因为这也有相同的旋转角度问题。
这是我的摆动代码
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100"
android:fromDegrees="-5"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:toDegrees="5" />
这是一个关于它的外观的视频 - 链接
在 bindView 逻辑上开始动画
((VHItem) holder).rlContainer.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View view)
{
if (buPostModelList != null)
{
startAnimationItem = true;
isDragCover = true;
isEditCoverImage = false;
for (int i = 0; i <= buPostModelList.size(); i++)
{
if (recyclerView.getChildAt(i) != null && recyclerView.getChildViewHolder(recyclerView.getChildAt(i)).getItemViewType() != TYPE_HEADER)
{
recyclerView.getChildAt(i).startAnimation(AnimationUtils.loadAnimation(context, R.anim.jiggle));
}
}
touchHelper.startDrag(holder);
}
return true;
}
});
编辑 示例项目 -链接
解决方案
当你移动视图时,旋转的中心仍然在起始位置,但视图仍然来回移动 5 度,所以它就像从旋转木马的中心移动到移动 5 度的外围在相同的时间内覆盖更远的距离。
我建议你换一个没有这个问题的ObjectAnimator 。
ObjectAnimator ValueAnimator
的这个子类提供对目标对象的动画属性的支持。此类的构造函数采用参数来定义将被动画化的目标对象以及将被动画化的属性的名称。然后在内部确定适当的设置/获取函数,动画将根据需要调用这些函数来为属性设置动画。
jiggle.xml
这是用于抖动效果的新ObjectAnimator xml。它与您的jiggle.xml非常相似。
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="100"
android:propertyName="rotation"
android:repeatCount="-1"
android:repeatMode="reverse"
android:valueFrom="-5"
android:valueTo="5"
android:valueType="floatType" />
VHItem
更新了具有动画师支持的视图持有者。
class VHItem extends RecyclerView.ViewHolder {
private ImageView ivCollectionImage, ivRemoveIcon;
private RelativeLayout rlContainer;
private Animator mAnimator;
public VHItem(View itemView) {
super(itemView);
ivCollectionImage = itemView.findViewById(R.id.ivCollectionImage);
ivRemoveIcon = itemView.findViewById(R.id.ivRemoveIcon);
rlContainer = itemView.findViewById(R.id.rlContainer);
}
// Start animation. Inflate the animator lazily.
public void startAnimator() {
if (mAnimator == null) {
mAnimator = AnimatorInflater.loadAnimator(context, R.animator.jiggle);
}
mAnimator.setTarget(itemView);
mAnimator.start();
}
// Stop the animation. Set the rotation back to zero.
public void stopAnimator() {
if (mAnimator != null) {
itemView.setRotation(0);
mAnimator.cancel();
}
}
}
您将需要更新适配器的其余部分以使用新动画。
推荐阅读
- c++ - C++ Autoclicker 不退出循环
- c++ - 放置 new 和 uninitialized_fill() 的行为
- pygame - 如何解决精灵移动速度过快的问题
- apache-flink - 在独立 flink 集群(Apache flink 1.9.0)上运行 apache Beam 字数统计示例时出错
- spring - 获取 org.springframework.beans.factory.BeanCreationException:使用名称创建 bean 时出错
- python - 利用类中的相同属性
- react-leaflet - 无法使用 JSON 变量设置 React-Leafletlet Maps CRS
- typo3 - TYPO3:如何显示页面树外文件夹中的记录
- python - 将列名添加到 Pandas DataFrame 时 Python 引发值错误
- javascript - Select2 分页在 Vue 组件中不起作用