1

我想在包含 ViewHolders 的 Android 中创建一个 RecyclerView,它会改变它们的宽度和高度,如下面的 GIF 所示。我为 RecyclerView 尝试了几个 LayoutManager,但我没有设法得到我想要的结果。

RecyclerView 应该是一维行。

任务的可视化

4

1 回答 1

0

嗨,您可以使用它来为 RecyclerView 中的视图设置动画,如下面的 GIF 所示:

在此处输入图像描述

我的适配器:

  public class StringAdapter extends RecyclerView.Adapter<StringAdapter.StringHolder> {
        private int defaultWidth = 0;
        private int defaultHeight = 0;
        private static final String[] strings = new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 8", "Item 10"};
        private int lastSelected = -1;
        private final RecyclerView.LayoutManager layoutManager;
        private static final int animValue = 50;
    
        StringAdapter(RecyclerView.LayoutManager layoutManager) {
            this.layoutManager = layoutManager;
        }
    
        @NonNull
        @Override
        public StringHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_holder, parent, false);
            return new StringHolder(v);
        }
    
        @Override
        public void onBindViewHolder(@NonNull StringHolder holder, int position) {
            holder.categories.setText(strings[position]);
            ViewGroup.LayoutParams param = holder.card.getLayoutParams();
            if (position == lastSelected) {
                param.width = defaultWidth + animValue;
                param.height = defaultHeight + animValue;
            } else {
                if (defaultWidth != 0 && defaultHeight != 0) {
                    param.width = defaultWidth;
                    param.height = defaultHeight;
                }
            }
        }
    
        @Override
        public int getItemCount() {
            return strings.length;
        }
    
        protected class StringHolder extends RecyclerView.ViewHolder {
    
            private final TextView categories;
            private final CardView card;
    
            public StringHolder(@NonNull View itemView) {
                super(itemView);
                categories = itemView.findViewById(R.id.categories);
                card = itemView.findViewById(R.id.cardCategories);
                card.setOnClickListener(v -> {
                    int currentPosition = this.getAbsoluteAdapterPosition();
                    selection(currentPosition, lastSelected);
                    lastSelected = currentPosition;
    
                });
            }
    
            private void selection(int newPosition, int oldPosition) {
                if (newPosition != oldPosition) {
                    ConstraintLayout newView = (ConstraintLayout) layoutManager.findViewByPosition(newPosition);
                    ConstraintLayout oldView = (ConstraintLayout) layoutManager.findViewByPosition(oldPosition);
                    if (newView != null) {
                        defaultWidth = card.getWidth();
                        defaultHeight = card.getHeight();
                        selectAnimate(newView.getChildAt(0));
                    }
                    if (oldView != null) {
                        deselectAnimate(oldView.getChildAt(0));
                    } else {
                        notifyItemChanged(oldPosition);
                    }
                }
            }
    
            private void selectAnimate(View view) {
                ValueAnimator select = ValueAnimator.ofInt(defaultWidth, defaultWidth + animValue);
                select.setInterpolator(new AccelerateDecelerateInterpolator());
                select.setDuration(300);
                select.start();
                select.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                        layoutParams.width = (int) animation.getAnimatedValue();
                        layoutParams.height = (int) (animation.getAnimatedValue()) + defaultHeight - defaultWidth;
                        view.requestLayout();
                    }
                });
            }
    
            private void deselectAnimate(View view) {
                ValueAnimator select = ValueAnimator.ofInt(defaultWidth + animValue, defaultWidth);
                select.setInterpolator(new AccelerateDecelerateInterpolator());
                select.setDuration(300);
                select.start();
                select.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                        layoutParams.width = (int) animation.getAnimatedValue();
                        layoutParams.height = (int) (animation.getAnimatedValue()) + defaultHeight - defaultWidth;
                        view.requestLayout();
                    }
                });
            }
        }
    }

我的主要活动

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
        recyclerView.setLayoutManager(layoutManager);
        StringAdapter adapter = new StringAdapter(layoutManager);
        recyclerView.setAdapter(adapter);
    }
}

我的MainActivity 布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".test.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
      />
</androidx.constraintlayout.widget.ConstraintLayout>

最后是这个MyHolder布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_marginStart="5dp">

    <androidx.cardview.widget.CardView
        android:id="@+id/cardCategories"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:cardCornerRadius="15dp"
        app:cardUseCompatPadding="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <TextView
            android:id="@+id/categories"
            android:layout_width="wrap_content"
            android:layout_height="35dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingStart="10dp"
            android:paddingEnd="10dp"
            android:text="Some Text"
            android:textSize="16sp" />
    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
于 2021-02-16T18:45:16.560 回答