背景 我正在开发一个锦标赛管理软件,我想在一个由Android设备提供的屏幕上显示当前的竞争者分类。 竞争者的数量超过了屏幕的垂直尺寸,因此我想使用一个漂亮的垂直动画smoth滚动从下到上显示它是无穷无尽的(当列表显示最后一个元素它将开始显示第一个,因为它会是一个循环。
方法 经过一些研究(抱歉,我没有所有参考资料),我想出了以下实现: 我在片段上使用带有适配器的recyclerview。为了自动向上滚动,我添加了一个计时器,可以在固定的itervals上滚动recycleview:
CountUpTimer recyclerViewAutoScroll = new CountUpTimer(1) {
public void onTick(long millis) {
recyclerView.scrollBy(0, mSpeed * 2);
if (!recyclerView.canScrollVertically(1)) {
recyclerView.scrollToPosition(0);
}
}
};
正在全局布局侦听器上创建和启动此计时器:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
layoutListener = () -> {
recyclerView.post(() -> recyclerViewAutoScroll.start());
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
}
CountUpTimer类只是一个使用android CountDowntimer实现的“无限”计时器。
使用这段代码,我可以定期向上滚动,问题是根本不是真的。有两个参数可供使用:计时器滴答时间,以及每次定时器“滴答”时所做的垂直滚动量。使其“平滑”的唯一方法是减少滚动运动,使用户非常非常慢。
为了完整起见,为了实现无限滚动效果,我在回收站视图中添加了一个滚动侦听器:
recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(5) {
@Override
public void onLoadMore(int currentPage) {
Timber.d("new Page " + currentPage);
recyclerView.post(() ->
{
itemAdapter.addModel(currentClassificationList);
if (currentPage > 2)
itemAdapter.removeModelRange(0, currentClassificationList.size());
});
}
我在那里做的只是添加两次classificationList以在底部有足够的空间来显示最后一个元素之后的列表顶部,并且我继续将列表添加到底部并且每次从recyclerview中删除即将到达列表的末尾。
所以我的问题是:如何实现recyclerview的真实滚动动画?正如我所说,这是在没有任何用户交互的情况下显示的,只是在不断显示和滚动分类的屏幕上。
更新
在一条评论建议之后,我用这样的方式用TimeAnimator类替换了计数计时器:
timeAnimator.setTimeListener(new TimeAnimator.TimeListener() {
@Override
public void onTimeUpdate(TimeAnimator timeAnimator, long l, long l1) {
Timber.d("elapsed: " + l1);
recyclerView.scrollBy(0, (int)(l1/ mSpeed));
if (!recyclerView.canScrollVertically(1)) {
recyclerView.scrollToPosition(0);
}
}
});
我也删除了不需要的帖子。 现在平滑度已经提高,但并不完美,当一个新项目即将从底部出现时,它仍然有点犹豫。 我现在正在寻找itemadapter来改进那里的任何计算和任何图像加载(我还添加了Picasso用于图像加载)但是它仍然不完美,它们在那里闪烁。