当前位置: 首页 > 知识库问答 >
问题:

Android回收查看动画问题

芮祺
2023-03-14

我正在尝试使回收器视图中的cardview展开。我让扩展部分正常工作,但是当向其添加过渡时,开始出现一些视觉错误。当没有屏幕外项目时,过渡工作正常,但是当我向回收器视图添加超过(在我的情况下)4个项目时,它开始发生。

带4件物品的GIF

包含 4 个以上项目的 GIF

当我禁用过渡动画时,卡视图扩展可以很好地处理超过4个项目。我认为问题与职位变化有关,但我找不到解决问题的任何解决方案。

我用来实现cardview扩展的指南可以在这里找到:https://stackoverflow.com/a/38623873/6673949

还有我完整的recyclerview适配器

public class BasketRecyclerAdapter extends RecyclerView.Adapter<BasketRecyclerAdapter.CustomViewHolder> {
private String letter;
private Context mContext;
private ColorGenerator generator = ColorGenerator.MATERIAL;
private List<Basket> baskets;
private int mExpandedPosition = -1;
private RecyclerView r1;

public BasketRecyclerAdapter(Context context, List<Basket> baskets, RecyclerView r1) {
    this.mContext = context;
    this.baskets = baskets;
    this.r1 = r1;

}

@Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.basket_menu_item, null);
    CustomViewHolder viewHolder = new CustomViewHolder(view);
    return viewHolder;
}

@Override
public void onBindViewHolder(final BasketRecyclerAdapter.CustomViewHolder holder, final int position) {

    String basketName = baskets.get(position).getBasketName();

    holder.basketName.setText(basketName);

    letter = "" + basketName.charAt(0);

    TextDrawable drawable = TextDrawable.builder()
            .buildRound(letter, generator.getColor(basketName));


    holder.imageLetter.setImageDrawable(drawable);

    final boolean isExpanded = position == mExpandedPosition;
    holder.expandedLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    holder.itemView.setActivated(isExpanded);
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                TransitionManager.beginDelayedTransition(r1);
            }
            notifyDataSetChanged();
        }
    });


}

可以做些什么来解决这个问题?谢谢。

编辑:我试图通过使用ListView而不是RecyclerView来使其工作,但是ListView适配器不会使用相同的代码扩展 - 将尝试找出原因。

Edit2:通过使用另一个名为“ExpandableLayout”的库让它工作,但似乎仍然无法弄清楚为什么没有额外的库它不起作用。

共有3个答案

司徒茂实
2023-03-14

我也有类似的问题。当屏幕外没有物品时,它工作得很好,但是当屏幕外有物品时,动画不能正常工作。解决方案是不要使用notifyDataSetChanged()更新适配器中的每一项。你只需要更新你想要展开的位置和你想要折叠的位置。我的猜测是屏幕外项目的视图持有者搞乱了动画。

    final boolean isExpanded = position == mExpandedPosition;
    vh.expandableView.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
    vh.itemView.setActivated(isExpanded);
    vh.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // collapse any currently expanded items
            if (mExpandedPosition != RecyclerView.NO_POSITION) {
                notifyItemChanged(mExpandedPosition);
            }

            //Update expanded position
            mExpandedPosition = isExpanded ? -1 : position;

            TransitionManager.beginDelayedTransition(mRecyclerView);

            //Expand new item clicked
            notifyItemChanged(position);

        }
    });
公冶泰
2023-03-14

我也有同样的问题。这是我如何计算出来的,就像你在GIF上展示的那样,有4个项目:)

在自定义适配器中,添加notifyItemChanged(位置)和notifyItemChanged(previousExpandedPosition),而不是notifyDataSetChanged():

public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
    final boolean isExpanded = position==mExpandedPosition;

    holder.expandedLayout.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
    holder.itemView.setActivated(isExpanded);

    if (isExpanded)
        mPreviousExpandedPosition = position;

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            TransitionManager.beginDelayedTransition(mRecyclerView);

            notifyItemChanged(mPreviousExpandedPosition);
            notifyItemChanged(position);
        }
    });
}

声明全局变量 mExpandedPosition 和 mPreviousExpandedPosition,并将它们初始化为 -1。

在适配器的构造函数中将mRecyclerView作为参数传递。

在您的片段或活动设置mRecyclerView.setItemAnimator(null)后设置适配器为回收视图,如下所示:

mRecyclerView.setAdapter(mRecyclerViewAdapter);
mRecyclerView.setItemAnimator(null);

这应该可以解决你的问题。

笪欣嘉
2023-03-14

我有类似的问题。添加适配器:

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

myAdapter.setHasStableIds(true);

 类似资料:
  • 我添加了一个自定义的< code > ItemTouchHelper。我的< code > recycle view 的SimpleCallback类,以添加“滑动时消除”功能,用户可以向左滑动项目,项目将从列表中删除。 我将视图可以“滑动”到左侧的量限制为视图长度的 10%,方法是将 dX(来自 onChildDraw())除以 10。但是,用户必须滑动的长度量是屏幕的 100%,以便项目被滑动

  • 假设我单击2位置的项目(记住其布局是颠倒的),然后调用 通知项目已更改(2[位置]) 在onBindViewHolder中,我在单击的项目上显示一些视图,因此它的高度会发生变化,当RecyclView测量它的孩子时,它会意识到它应该移动一些项目以使该项目的高度变化看起来引人入胜))。DefaultItemAnimator会处理它,但它会将所有低于“U are??? Omg谢谢u”项目的孩子向下移动

  • 我正在使用使用从中提供数据的。我想禁用事件的动画,但将它们保留为//。我尝试在使用的上调用,但动画仍然出现。如果我调用,所有动画都会按预期成功删除。 我尝试查看实现,似乎如果是,将通过保留旧的viewHolder并将其交叉淡出到新的viewHolder来对更改事件进行动画处理。我不想这样。如果是,则旧的和新的viewHolders将是相同的对象,取而代之的是从x到x的动画(即没有实际移动)。然而,

  • 对不起我的英语我是法语:) 我正在尝试学习如何在Android studio中编码,我从一个回收器视图开始,不幸的是我有一个错误我不知道如何修复它。 事先谢谢你的帮助 错误: mainactivity.java(所有代码) MainActivity中的错误部分 与之链接的外部代码: 再次提前道谢,祝你有美好的一天:)

  • 我有一个recycle view,用户可以在其中将一个项目拖放到recycle view中的不同位置。 到目前为止,一切正常。 我的问题始于RecyclerView中的项目超过了它可以显示的数量。所以当它回收他的内容时。当用户将项目拖放到不同的位置,然后滚动离开该零件时,不会保存位置更改。用户只看到项目的旧位置。 您可以在下面的.gif中看到此问题。 我已经尝试了几件事,比如: 和 在我的onBi

  • 我是显示隐藏的视图后,刷了两个按钮“删除”和“取消”。在我的xml项目行中,我有2个内部关系 此处ItemTouchHelper实现 这里是观众 如果单击be more correct buttons但未在swipe后首次尝试更新,则在swipe模式下单击项目,并且日志显示前3次单击是swipe方向 在swipe log.d(“swipe”,“direction=”+direction);