#android #android-recyclerview #android-animation
#Android #android-recyclerview #android-анимация
Вопрос:
В моем recyclerview я хочу, чтобы все элементы покачивались / колебались / покачивались, когда пользователь держит элемент и перемещает его. Проблема, с которой я сталкиваюсь, заключается в том, что когда пользователь удерживает элемент и перемещает его в том же типе представления, покачивание в порядке, но когда кто-то перетаскивает его в верхнюю часть recyclerview (который является заголовком, созданным как viewtype в recyclerview), покачивание значительно увеличивается.
Поиграв со значениями, я понял, что это связано с тем, что, хотя угол поворота тот же, чем дальше он удалялся от центра элемента, вращение увеличивалось.
Я также пытался сделать это с помощью object animator, но это не помогло, поскольку у него тоже была такая же проблема с углом поворота.
Вот мой код для покачивания
<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 amp;amp; recyclerView.getChildViewHolder(recyclerView.getChildAt(i)).getItemViewType() != TYPE_HEADER)
{
recyclerView.getChildAt(i).startAnimation(AnimationUtils.loadAnimation(context, R.anim.jiggle));
}
}
touchHelper.startDrag(holder);
}
return true;
}
});
Редактировать
Пример проекта — ссылка
Комментарии:
1. Не могли бы вы добавить код, в котором вы применяете эту анимацию?
2. @DanielBeleza Я применяю его к прослушивателю длинного щелчка, а затем для всех остальных ячеек устанавливается логическое значение, которое затем анимируется в представлении привязки и во всех видимых ячейках
3. Извините, но это недостаточно ясно. Было бы действительно полезно, если бы вы могли просто отредактировать свой пост и добавить больше кода при применении анимации.
4. Из видео я думаю, что ваша проблема связана с вашими значениями сводных точек, но поскольку я не уверен, как вы программно реализуете свою анимацию… Я прихожу к такому выводу, потому что, как вы сказали, «чем дальше он отодвинулся от центра элемента».
5. @DanielBeleza Я добавил код BindView, в котором начинается анимация
Ответ №1:
При перемещении вида центр поворота остается в исходном положении, но вид по-прежнему перемещается на пять градусов вперед и назад, так что это похоже на перемещение от центра карусели к периферии, где движение на пять градусов покрывает большее расстояние за то же время.
Я предлагаю вам перейти к ObjectAnimator, у которого нет этой проблемы.
ObjectAnimator
Этот подкласс ValueAnimator обеспечивает поддержку анимации свойств целевых объектов. Конструкторы этого класса принимают параметры для определения целевого объекта, который будет анимирован, а также имя свойства, которое будет анимировано. Затем соответствующие функции set / get определяются внутренне, и анимация будет вызывать эти функции по мере необходимости для анимации свойства.
jiggle.xml
Это новый XML-файл ObjectAnimator для эффекта покачивания. Это очень похоже на ваш 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();
}
}
}
Вам нужно будет обновить остальную часть адаптера для работы с новой анимацией.