Подтвердить что ты не робот

Анимация RecyclerView при нажатии на элемент

Я пытаюсь реализовать свою собственную анимацию recyclerview Animation - я хотел бы достичь этого, не используя внешние библиотеки. Вот как должна выглядеть теоретическая анимация.

enter image description here

Пользователь нажимает элемент в списке и появляется анимация, которая открывает другой вид.

На высоком уровне с минимальным кодом, возможно, просто псевдокодом, каким будет процесс для создания такой анимации?

Также я хотел бы отметить, что анимация также должна быть выполнена в обратном порядке, если пользователь нажимает один и тот же элемент или другой элемент

Я не знаком с классом RecyclerView и хотел бы узнать больше об этом и о любых связанных с ним анимациях.

4b9b3361

Ответ 1

Решение:

Как я решил эту проблему, было реализовать слушателя View.OnClickListener для класса ViewHolder, который extends RecyclerView.ViewHolder. Итак, мы получаем следующий код:

public static class ExampleViewHolder extends RecyclerView.ViewHolder 
    implements View.OnClickListener {

    private int originalHeight = 0;
    private boolean isViewExpanded = false;
    private YourCustomView yourCustomView

    // ..... CODE ..... //

}

В процессе анимации используются переменные originalHeight и isViewExpanded. В конструкторе я инициализирую представление View.OnClickListener следующим образом:

public ExampleViewHolder(View v) {
     super(v);
     v.setOnClickListener(this);

     // Initialize other views, like TextView, ImageView, etc. here

     // If isViewExpanded == false then set the visibility 
     // of whatever will be in the expanded to GONE

     if (isViewExpanded == false) {
         // Set Views to View.GONE and .setEnabled(false)
         yourCustomView.setVisibility(View.GONE);
         yourCustomView.setEnabled(false);
     }

 }

Теперь, когда конструктор позаботился о том, что мы хотим настроить, что происходит, когда пользователь нажимает на отдельный элемент RecyclerView. Классы, которые будут полезны здесь, будут объекты ValueAnimator и Animation. Мы переопределяем метод onClick следующим образом:

@Override
public void onClick(final View view) {
    // If the originalHeight is 0 then find the height of the View being used 
    // This would be the height of the cardview
    if (originalHeight == 0) {
            originalHeight = view.getHeight();
        }

    // Declare a ValueAnimator object
    ValueAnimator valueAnimator;
        if (!mIsViewExpanded) {
            yourCustomView.setVisibility(View.VISIBLE);
            yourCustomView.setEnabled(true);
            mIsViewExpanded = true;
            valueAnimator = ValueAnimator.ofInt(originalHeight, originalHeight + (int) (originalHeight * 2.0)); // These values in this method can be changed to expand however much you like
        } else {
            mIsViewExpanded = false;
            valueAnimator = ValueAnimator.ofInt(originalHeight + (int) (originalHeight * 2.0), originalHeight);

            Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out

            a.setDuration(200);
            // Set a listener to the animation and configure onAnimationEnd
            a.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    yourCustomView.setVisibility(View.INVISIBLE);
                    yourCustomView.setEnabled(false);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });

            // Set the animation on the custom view
            yourCustomView.startAnimation(a);
        }
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                view.getLayoutParams().height = value.intValue();
                view.requestLayout();
            }
        });


        valueAnimator.start();

    }

Теперь, когда вы касаетесь индивидуального вида карты на RecyclerView (при условии, что у вас есть настройка CardView, тогда она должна расширяться). Обязательно объявите свой customView правильно в своем XML файле (например, если вы хотите, чтобы CardView для раскрытия вниз, когда вы касаетесь его, затем правильно назначьте customView под другими представлениями и установите видимость на исчезновение, когда вы его объявите, а затем, когда анимация начнется, как в коде выше, установите видимость на Visible и включите представление.

Надеюсь, это поможет кому-то.

Ответ 2

Более простой альтернативой для ответа @AndyRoid является использование свойства android:animateLayoutChanges="true". Таким образом, вам не нужно писать какой-либо код анимации; однако, это не путь, если вам нужно управлять анимацией.

Вам все равно нужно создать OnClickListener:

class CardTapListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        View someView = v.findViewById(R.id.view_to_expand);

        if (someView.getVisibility() == View.GONE) {
            someView.setVisibility(View.VISIBLE);
        }
        else if (someView.getVisibility() == View.VISIBLE){
            someView.setVisibility(View.GONE);
        }

    }
}

Прикрепите его к каждому ViewHolder:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_layout, viewGroup, false);
    v.setOnClickListener(new CardTapListener());
    return new ItemViewHolder(v);
}

Не забудьте свернуть представления при привязке нового элемента:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
    ...
    // Collapse (probably opened by user previously) view
    ItemViewHolder itemHolder = (ItemViewHolder) viewHolder;
    itemHolder.description.setVisibility(View.GONE);
    ...

}

view_holder_layout.xml:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:orientation="vertical">

 ...

    <AnyViewHere
        android:visibility="gone"
        android:id="@+id/view_to_expand" />

 </LinearLayout>