Detect animation finish in Android's RecyclerView

后端 未结 9 1628
后悔当初
后悔当初 2020-12-29 02:31

The RecyclerView, unlike to ListView, doesn\'t have a simple way to set an empty view to it, so one has to manage it manually, making empty view vi

相关标签:
9条回答
  • 2020-12-29 02:59

    There is a method in the ItemAnimator class that is called when all item animations are finished:

        /**
         * Method which returns whether there are any item animations currently running.
         * This method can be used to determine whether to delay other actions until
         * animations end.
         *
         * @return true if there are any item animations currently running, false otherwise.
         */
         public abstract boolean isRunning();
    

    You can override it to detect when all item animations have ended:

    recyclerView.itemAnimator = object : DefaultItemAnimator() {
        override fun isRunning(): Boolean {
            val isAnimationRunning = super.isRunning()
            if(!isAnimationRunning) {
                // YOUR CODE
            }
            return isAnimationRunning
        }
    }
    
    0 讨论(0)
  • 2020-12-29 03:00

    Extending Roman Petrenko's answer, if you are using androidx recycler view with kotlin, you can do something like that:

            taskListRecycler.apply {
                itemAnimator = object : DefaultItemAnimator() {
                    override fun onAddFinished(item: RecyclerView.ViewHolder?) {
                        super.onAddFinished(item)
                        //Extend
                    }
    
                    override fun onRemoveFinished(item: RecyclerView.ViewHolder?) {
                        super.onRemoveFinished(item)
                        //Extend
                    }
                }
                layoutManager = LinearLayoutManager(context)
                adapter = taskListAdapter
            }
    
    0 讨论(0)
  • 2020-12-29 03:01

    Currently the only working way I've found to solve this problem is to extend ItemAnimator and pass it to RecyclerView like this:

    recyclerView.setItemAnimator(new DefaultItemAnimator() {
        @Override
        public void onAnimationFinished(RecyclerView.ViewHolder viewHolder) {
            updateEmptyView();
        }
    });
    

    But this technique is not universal, because I have to extend from concrete ItemAnimator implementation being used by RecyclerView. In case of private inner CoolItemAnimator inside CoolRecyclerView, my method will not work at all.


    PS: My colleague suggested to wrap ItemAnimator inside the decorator in a following manner:

    recyclerView.setItemAnimator(new ListenableItemAnimator(recyclerView.getItemAnimator()));
    

    It would be nice, despite seems like overkill for a such trivial task, but creating the decorator in this case is not possible anyway, because ItemAnimator has a method setListener() which is package protected so I obviously can't wrap it, as well as several final methods.

    0 讨论(0)
提交回复
热议问题