Как использовать анимацию поворота при перетаскивании вида, чтобы центральное положение постоянно менялось? Решить вопрос от степени к степени

1

В моем обзоре переработчика я хочу, чтобы все элементы перемешивались/колебались/покачивались, когда пользователь удерживает элемент и перемещает его. Проблема, с которой я сталкиваюсь, заключается в том, что когда пользователь удерживает элемент и перемещает его в том же типе представления, покачивание в порядке, но когда кто-то перетаскивает его в верхнюю часть просмотра реселлера (который представляет собой заголовок, созданный как вид представления в представлении рециркулятора), покачивание сильно увеличивается.

Поэкспериментировав со значениями, я понял, что это потому, что, хотя угол поворота один и тот же, чем дальше он удаляется от центра предмета, тем больше вращение используется для увеличения.

Я попытался сделать это с помощью объектного аниматора, но это не помогло, так как у него была та же проблема угла поворота.

Вот мой код покачивания

<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;
                    }
                });

РЕДАКТИРОВАТЬ Образец проекта - ссылка

Теги:
android-recyclerview
android-animation

1 ответ

2
Лучший ответ

При перемещении вида центр вращения остается в исходном положении, но вид все еще перемещается на пять градусов назад и вперед, так что это похоже на перемещение от центра карусели к периферии, где движение на пять градусов покрывает большее расстояние за то же время.

Я предлагаю вам перейти к ObjectAnimator, который не имеет этой проблемы.

ObjectAnimator
Этот подкласс ValueAnimator обеспечивает поддержку анимации свойств целевых объектов. Конструкторы этого класса принимают параметры, чтобы определить целевой объект, который будет анимирован, а также имя свойства, которое будет анимировано. Соответствующие функции set/get затем определяются внутри, и анимация будет вызывать эти функции по мере необходимости для анимации свойства.

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();
        }
    }
}

Вам нужно будет обновить оставшуюся часть адаптера для работы с новой анимацией.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню