gpt4 book ai didi

android - 在 RecyclerView 中分别对 View 进行动画处理

转载 作者:太空狗 更新时间:2023-10-29 13:12:33 26 4
gpt4 key购买 nike

我还没有调查这么多,但是我之前没有看到过这样的功能,也没有找到很多关于这个主题的信息,所以我认为最好联系 SO 看看是否有人有之前玩过这个想法,可以提供任何建议。如果没有,我会在找到解决方案后在下面发布解决方案。


期望的结果

目前我有一个填充了内容的GridView。我在 GridView 顶部有一个 FloatingActionButton,当用户点击 FAB 时,我想显示一个新的 View。点击时,我希望每个单独的 GridView 项目旋转并向屏幕边缘移动,从而导致整个 GridView 分开,为新的 View< 腾出空间 从底部滑入。当第二个 View 出现时,RecyclerView 将变得不可滚动,并且会保持这种状态直到用户返回,这样做会导致相反的动画发生,带来 >ViewHolder 回到中心并缩小间隙。


请原谅我试图解决我的问题。 :)

GridView 预动画 enter image description here

动画后的 GridView enter image description here

每个 View 项都应该相互独立地动画,结束动画将模拟一种爆炸 RecyclerView 效果。


目前可能的方法/尝试过

我目前正在阅读有关 RecyclerView 各个元素行为的信息。我也从这个 Android Summit video 得到了一些很好的信息关于 RecyclerView 动画。

现在我认为有几种不同的方法:

  1. 使用两个不同的 LayoutManager 并尝试在它们之间制作动画。

  2. 使用 ItemDecorator 改变每个 ViewHolder 的边距和角度。


任何意见或建议将不胜感激,我会在解决问题时更新上面的列表。

谢谢!

最佳答案

事实证明,能够在 RecyclerView 中为 View 设置动画非常简单!您只需要一个自定义的 RecyclerView.LayoutManager,然后您就可以访问所有可见的 View ,以享受动画乐趣。

这里的主要方法是 getChildCount()getChildAt(int index),这两个方法如下面的 getVisibleViews() 您可以访问 RecyclerView 当前显示的所有 View 。然后,我使用一个简单的 View.animate() 调用将每个 View 动画化到所需的 X 位置和旋转。我相信这也适用于所有其他类型的动画!我现在有了我想要的东西。 :)

这是自定义 LayoutManager,请记住,如果您不扩展预定义的 LayoutManager,例如 GridLayoutManagerLinearLayoutManager,您需要提供更多方法,例如 generateDefaultLayoutParams()

public class AnimatingGridLayoutManager extends GridLayoutManager {

private static final int PARTED_ANIMATION_DURATION = 200;
private static final int PARTED_ANIMATION_VARIANCE = 20;
private static final int PARTED_ANIMATION_OFFSET = 25;
private static final int PARTED_ANIMATION_ANGLE = 15;

private boolean itemsParted;

...

public void setItemsParted(boolean itemsParted, Activity context) {
Display display = context.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;

if (this.itemsParted != itemsParted) {
this.itemsParted = itemsParted;
if (itemsParted) {
partItems(context, screenWidth);
} else {
closeItems(screenWidth);
}
}
}

private void partItems(Context context, int screenWidth) {
List<View> visibleViews = getVisibleViews();
for (int i = 0; i < visibleViews.size(); i++) {
int viewWidth = visibleViews.get(i).getWidth();
int offset = ViewUtils.getPixelsFromDp(getRandomNumberNearInput(PARTED_ANIMATION_OFFSET), context);
int xPos = (-viewWidth) + offset;
int rotation = getRandomNumberNearInput(-PARTED_ANIMATION_ANGLE);

if (viewPositionIsRight(i)) {
// invert values to send view to end of screen instead of start
xPos = screenWidth - offset;
rotation = -rotation;
}

visibleViews.get(i).animate()
.x(xPos)
.rotation(rotation)
.setDuration(PARTED_ANIMATION_DURATION)
.setInterpolator(new FastOutSlowInInterpolator());
}
}

private void closeItems(int screenWidth) {
List<View> visibleViews = getVisibleViews();
for (int i = 0; i < visibleViews.size(); i++) {
int xPos = 0;

if (viewPositionIsRight(i)) {
xPos = screenWidth / 2;
}

visibleViews.get(i).animate()
.x(xPos)
.rotation(0)
.setDuration(PARTED_ANIMATION_DURATION)
.setInterpolator(new FastOutSlowInInterpolator());
}
}

private boolean viewPositionIsRight(int position) {
// if isn't 2 row grid new logic is needed
return position % 2 != 0;
}

private int getRandomNumberNearInput(int input) {
Random random = new Random();
int max = input + PARTED_ANIMATION_VARIANCE;
int min = input - PARTED_ANIMATION_VARIANCE;
return random.nextInt(max - min) + min;
}

private List<View> getVisibleViews() {
List<View> visibleViews = new ArrayList<>();
for (int i = 0; i < getChildCount(); i++) {
visibleViews.add(getChildAt(i));
}
return visibleViews;
}
}

关于android - 在 RecyclerView 中分别对 View 进行动画处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38310563/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com