gpt4 book ai didi

android - GridView 上的动画在滚动时变得困惑

转载 作者:可可西里 更新时间:2023-10-31 22:04:44 26 4
gpt4 key购买 nike

我想做的是在单击时制作一个 View 摇动 并在再次单击时停止摇动,我做到了,但是当我滚动 GridView 时一切都变得一团糟,摇动动画出现在另一个未被点击的 View 上。

这里有一个更清楚的解释:http://i.imgur.com/IDv7vJ6.gif

我不知道为什么这些其他观点在动摇。

这是我的代码:

public class PeopleFragmentGridAdapter extends BaseAdapter {

private List<Person> people = new ArrayList<>();
private Context context;
private Map<Integer, Boolean> animating;
private Map<Integer, ObjectAnimator> animators;

public PeopleFragmentGridAdapter(Context context, List<Person> people) {
this.context = context;
this.people.addAll(people);
this.animating = new HashMap<>();
this.animators = new HashMap<>();
}

@Override
public int getCount() {
return people.size();
}

@Override
public Person getItem(int position) {
return people.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder ViewHolder;
final Person p = people.get(position);

if (convertView == null) {
convertView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.fragment_people_grid_peoples_item, null);
ViewHolder = new ViewHolder();
ViewHolder.peopleGridItem = (PeopleGridItem) convertView.findViewById(R.id.fragment_people_grid_peoples_item_item);
convertView.setTag(ViewHolder);
} else {
ViewHolder = (ViewHolder) convertView.getTag();
}


convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
p.setSelected(!p.isSelected());
notifyDataSetChanged();
}
});

if (animators.get(p.getId()) == null)
animators.put(p.getId(), ObjectAnimator.ofFloat(convertView, "rotation", 0, -2, 0, 2, 0));
if (animating.get(p.getId()) == null)
animating.put(p.getId(), false);

if (p.isSelected()) {
if (!animating.get(p.getId())) {
animating.put(p.getId(), true);
animators.get(p.getId()).setTarget(convertView);
animators.get(p.getId()).setRepeatCount(ObjectAnimator.INFINITE);
animators.get(p.getId()).setDuration(300);
animators.get(p.getId()).start();
}
} else {
animators.get(p.getId()).setTarget(convertView);
animating.put(p.getId(), false);
animators.get(p.getId()).end();
animators.get(p.getId()).cancel();
}

return convertView;
}
}

有什么问题吗?

最佳答案

其他 View 抖动的原因是 Android 实现 GridView 的方式。为了保留内存,它会回收 View ,以便只有那些显示在屏幕上(或即将显示)的 View 才会保存在内存中。任何被回收的 View 都被放入一个未使用的 View 池中,这些 View 可以在将来重用。这是参数“convertView”获取其 View 的地方。

这意味着您的工作是在屏幕外保持对象的状态。

if (convertView == null) {
convertView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.fragment_people_grid_peoples_item, null);
ViewHolder = new ViewHolder();
ViewHolder.peopleGridItem = (PeopleGridItem) convertView.findViewById(R.id.fragment_people_grid_peoples_item_item);
convertView.setTag(ViewHolder);
} else {
ViewHolder = (ViewHolder) convertView.getTag();
}

输入 else 语句——其中 convertView != null——表明您收到了一个回收 View ,而不是膨胀一个新 View 。正是在这里,您应该防止回收 View 继续摇晃。

编辑:我更仔细地查看了您的代码,我认为您实际上考虑到了我之前提到的内容(但没有成功),但我将保留它以防万一帮助别人。对于您的情况,我认为问题在于您无法停止 ObjectAnimator。

if (animators.get(p.getId()) == null)
animators.put(p.getId(), ObjectAnimator.ofFloat(convertView, "rotation", 0, -2, 0, 2, 0));

如果当前 Person 的动画师为空。你创造一个新的。假设您单击了 person1。 ObjectAnimator1 开始为 person1 制作动画。您向下滚动,此 View 将重新用于 person13。 ObjectAnimator13 被创建,然后被告知结束并取消。无论 ObjectAnimator13 说什么,ObjectAnimator1 仍然对被重用的 View 进行动画处理。

要解决此问题,您可能需要将 Person 的当前 ID 存储在 ViewHolder 中,这样您可以做的第一件事就是结束任何先前存在的动画。可能更好的方法是将 ObjectAnimator 存储在 ViewHolder 中,然后不需要在 HashMap 中搜索它。

关于android - GridView 上的动画在滚动时变得困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29400104/

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