【问题标题】:RecyclerView : How to create insert animation effect?RecyclerView:如何创建插入动画效果?
【发布时间】:2015-03-11 12:09:13
【问题描述】:

我有一个ReyclerView 与一个LinearLayoutManager 和一个Adapter<ViewHolder> 一起工作。我有一个我想在 recyclerview 中显示的项目列表,其中包含插入(滑入)动画。我该怎么办?

我想根据项目的索引以线性增加的延迟显示动画。

目前,如果我使用 2 个按钮,“添加”和“删除”,然后在 recyclerview 上执行相应的操作(notifyItemInserted()notifyItemRemoved(),动画效果很好。

如果我以编程方式循环数据集并添加项目,再次使用notifyItemInserted(),我看不到任何动画。我只是看到所有项目几乎同时出现。

如果我使用具有线性延迟的 Asynctasks,然后在 OnPostExecute() 中添加/删除项目,我仍然看不到任何动画。此外,如果多个插入线程正在等待所有删除线程完成(删除线程没有运行的地方),我发现可能会遇到死锁。

我做错了什么?

我已经在 SO 上解决了与此相关的大部分问题,并且花了几天时间在 recyclerview 的动画部分中寻找,仍然没有运气。

【问题讨论】:

    标签: android animation delay android-recyclerview


    【解决方案1】:

    下面是我在Adapter 中添加动画的方法。这将为推动效果设置动画,行从右侧进入。

    先在xml中定义动画(res/anim/push_left_in.xml

    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="100%p" android:toXDelta="0"
            android:duration="300"/>
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="300" />
    </set>
    

    然后在你的适配器中设置它

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            row = inflater.inflate(R.layout.music_list_item, null);
        } else {
            row = convertView;
        }
    
        ...
    
        //Load the animation from the xml file and set it to the row
        Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_in);
        animation.setDuration(500);
        row.startAnimation(animation);
    
        return row;
    }
    

    每次添加新行时都会显示此动画,它应该适用于您的情况。

    编辑

    这是使用RecyclerView 添加动画的方法

    @Override
    public void onBindViewHolder(ViewHolder holder, int position)
    {
        holder.text.setText(items.get(position));
    
        // Here you apply the animation when the view is bound
        setAnimation(holder.container, position);
    }
    
    /**
     * Here is the key method to apply the animation
     */
    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition)
        {
            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.push_left_in);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }
    

    【讨论】:

    • 看看this answer。作者解释了当您使用RecyclerView 时在何处添加动画。 @milindbableshwar
    • 我已将相关代码编辑为我的答案,请看一下。 @milindbableshwar
    • 完美!这是有效的。一个后续问题,如何动画项目删除?我的意思是,如果我要以编程方式删除项目列表,我应该从哪里开始删除项目动画?
    • 很遗憾,我不知道。我做了一些研究,但找不到任何相关的答案。我认为创建一个新问题来解决这个问题是合适的。 @milindbableshwar
    • lastPosition 是如何初始化或定义的?我假设它(位置 - 1)定义为方法变量。
    【解决方案2】:

    将此行添加到您的 RecyclerView xml:

    android:animateLayoutChanges="true"

    【讨论】:

    • @Hmm 很高兴它有帮助!
    • 只有在回收站视图(notifyItemChange、notifyItemRemove 等)不进行更改时才能使用此参数
    • 这经常会破坏 RecyclerViews,另见 stackoverflow.com/q/26477660/4607733
    【解决方案3】:

    这对我有用:

    animation.setStartOffset(position*100);
    

    【讨论】:

    • 您能详细说明一下吗?
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 2012-10-10
    • 2016-10-23
    • 2012-11-23
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2017-08-09
    相关资源
    最近更新 更多