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

RecyclerView上没有关于项目移除的动画

杨成礼
2023-03-14

我是第一次使用 RecyclerView。一切正常,除了没有关于项目删除的动画,即使添加项目的动画工作正常。

我没有设置任何自定义项目动画师,但根据留档:

默认情况下,在<code>RecyclerView</code>中启用添加和删除项目的动画。

因此,删除时的动画应该可以正常工作。

我希望在删除时具有默认动画,但无法使其正常工作。

这是我如何设置RecycleView:

private void setupRecyclerView() {
  mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view);
  mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
  View emptyView = mRootView.findViewById(R.id.empty_view);
  mAdapter = new RoutineAdapter(getActivity(), mRoutineItems, emptyView);
  mRecyclerView.setAdapter(mAdapter);
}

这是我的适配器

private class RoutineAdapter
      extends RecyclerView.Adapter<RoutineAdapter.ViewHolder> {

private final Context mContext;
private List<RoutineItem> mData;
private View mEmptyView;

    public RoutineAdapter(Context context, List<RoutineItem> data, View emptyView) {
      mContext = context;
      mData = data;
      mEmptyView = emptyView;
      setEmptyViewVisibility();
    }

    public void add(RoutineItem routineItem, int position) {
      mData.add(position, routineItem);
      setEmptyViewVisibility();
      notifyItemInserted(position);
    }

    public void remove(int position){
      mData.remove(position);
      setEmptyViewVisibility();
      notifyItemRemoved(position);
    }

    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      final View view = LayoutInflater.from(mContext).inflate(
          R.layout.fragment_routines_list_item, parent, false);
      return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
      final RoutineItem routineItem = getItem(position);
      holder.circle.setBackgroundResource(
          colorNumberToDrawableResource(routineItem.colorNumber));
      holder.initial.setText(routineItem.routineName.substring(0, 1));
      holder.routineName.setText(routineItem.routineName);
      holder.lastTimeDone.setText(routineItem.lastTimeDoneText);
      if (routineItem.isSelected) {
        holder.itemView.setBackgroundColor(
            getResources().getColor(R.color.background_item_selected));
      } else {
        holder.itemView.setBackgroundResource(
            R.drawable.darker_background_on_pressed);
      }
      holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          mPresenter.onRoutineClicked(routineItem.routineName);
        }
      });
      holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
          mPresenter.onRoutineLongClicked(routineItem.routineName);
          return true;
        }
      });
    }

    @Override
    public int getItemCount() {
      return mData.size();
    }

    public RoutineItem getItem(int position) {
      return mData.get(position);
    }

    private void setEmptyViewVisibility() {
      if (getItemCount() == 0) {
        mEmptyView.setVisibility(View.VISIBLE);
      } else {
        mEmptyView.setVisibility(View.GONE);
      }
    }

    class ViewHolder extends RecyclerView.ViewHolder {
      public final View circle;
      public final TextView initial;
      public final TextView routineName;
      public final TextView lastTimeDone;

      public ViewHolder(View view) {
        super(view);
        circle = view.findViewById(R.id.circle);
        initial = (TextView) view.findViewById(R.id.initial);
        routineName = (TextView) view.findViewById(R.id.routine_name);
        lastTimeDone = (TextView) view.findViewById(R.id.last_time_done);
      }
    }
}

Fragment_routines_list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:minHeight="@dimen/standard_list_item_height"
  android:paddingBottom="8dp"
  android:background="@drawable/darker_background_on_pressed"
  android:clickable="true">
    ......
</RelativeLayout>

我做错了什么,导致默认删除动画不起作用?

共有3个答案

袁晟
2023-03-14

使用通知数据删除(位置)而不是通知数据更改()如下所示

myDataset.remove(position);
notifyItemRemoved(position);

因为notifyDataSetChanged()只是通知更新的数据,没有任何动画。

东郭海阳
2023-03-14

解决了。

问题是,在调用<code>mAdapter之后。删除(位置),我代码的另一部分是调用<code>mAdapter。notifyDataSetChanged(),我假设它会停止移除动画。

总而言之,如果您在动画播放过程中调用< code > madapter . notifydatasetchanged ,动画将会停止。

陆宇航
2023-03-14

从回收站视图中删除项目的正确方法是从数据集中删除该项目,然后告诉适配器该项目已被删除,如下所示

myDataset.remove(position); // myDataset is List<MyObject>
mAdapter.notifyItemRemoved(position);
 类似资料:
  • 我在片段的底部有一个水平图像滑块。片段的顶部显示了一些细节。一旦用户点击底部的图像,想法是从图像滑块中删除该图像,并在片段中显示其信息。现在,信息显示出来,但图像不会从中删除。下面是我在最外层布局的中编码的内容。我试过了所有我能找到的相关答案,但都没有奏效。它们都在代码里。请让我知道我做错了什么或者错过了什么。 适配器的完整代码 }

  • 我使用了一个带有的光标加载器,除了每次从RecyclerView中移除一个项目时,最后一个项目会闪烁,如下所示 最后一项闪烁 我的删除代码是 或 但这些都不奏效,更不用说我真的希望动画能奏效。 编辑:断点上载: onCreate: “main@4668”prio=5 tid=0x2 nid=na可运行java.lang.thread.state:可在com.jackz314.todo.histor

  • 我的RecyclView defaultItemAnimator有问题。当我使用elle fyItemRemve()删除我的一个项目时,我还会在另一个特定索引上调用elle fyItemChanged()来更改其中的文本。在删除动画期间,我在其上调用的项目通知fyItemChanged()会更改其文本,但会做一些看起来很傻的动画,像拇指疼痛一样突出。(它会立即移动到新位置,而其余的则会顺利移动到新

  • 必备工具 没有金刚钻,不揽瓷器活。趁手的兵器往往让你事半功倍。为了更好地参与翻译计划,你最好能够熟练使用Sphinx和Subversion(SVN)。如果二者都不熟悉,那么也可以将无格式的译文文稿通过邮件发送给我。 Subversion 用于进行版本控制。如果你是Linux用户,那么命令行版本就挺好。如果你是Windows用户,那么推荐使用TortoiseSVN。 在使用SVN进行提交时,为了能够

  • 在大多数情况下,项目是您为一个网站编写的一个脚本。 项目是独立的,但您可以将另一个项目作为模块导入 from projects import other_project 一期工程有5个状态:TODO,STOP,CHECKING,DEBUG和RUNNING TODO - 创建一个脚本来编写 STOP- 您可以将项目标记为STOP您希望它停止(= =)。 CHECKING- 修改正在运行的项目时,为防

  • 我正在用AppWidgetHostViews填充RecyclerView。它们被排序一个比一个低,每个都有删除按钮旁边。这就是我如何设置RecyclerView和适配器(Event.Object是AppWidgetHostView): 这是保存AppWidgetHostViews的适配器: 因此它再次为适配器设置数据并通知数据集已更改。 但问题是,当我单击“删除”按钮时,项目没有被正确删除。Vie