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

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

Введите описание изображения здесь

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

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

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

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

Solutions Collecting From Web of "Анимация RecyclerView при нажатии на элемент"

Решение:

То, как я решил эту проблему, заключалось в том, чтобы реализовать View.OnClickListener ViewHolder класс 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 и включите представление.

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

Более простой альтернативой для ответа @ 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>