视差标题效果与RecyclerView

我想改变我的ListView我目前已经结束使用RecyclerView所以我可以使用StaggeredGridLayoutManager但RecyclerView没有能力添加像ListView的头。

通常使用ListView,我在标题中设置一个空视图,并将图像放在列表视图的下方,并通过滚动列表来翻译底部图像以创建Parallax效果。

所以,如果没有标题,我怎样才能创建与RecyclerView相同的视差效果?

所以今天我试图在RecyclerView上存档这个效果。 我能够做到这一点,但由于代码太多,我会粘贴在这里我的github项目,我会解释一些项目的关键点。

https://github.com/kanytu/android-parallax-recyclerview

首先,我们需要查看RecyclerView.Adapter类的getItemViewType 。 这个方法定义了我们正在处理的视图类型。 该类型将传递给onCreateViewHolder ,在那里我们可以膨胀不同的意见。 所以我做的是:检查这个位置是否是第一个。 如果是这样,然后膨胀标题,如果没有膨胀正常的行。

我还添加了一个CustomRelativeLayout来剪辑视图,所以我们没有任何分隔符和行顶部的问题。

从这一点上,你似乎知道其背后的逻辑的其余部分。

最终的结果是:

在这里输入图像描述

编辑:

如果您需要在适配器中插入某些内容,请确保通过在notifyItemChanged/Inserted方法中添加1来通知正确的位置。 例如:

 public void addItem(String item, int position) { mData.add(position, item); notifyItemInserted(position + 1); //we have to add 1 to the notification position since we don't want to mess with the header } 

我做的另一个重要的编辑是滚动逻辑。 我正在使用的mCurrentOffset系统没有使用项目插入,因为如果添加项目,偏移量将会改变。 所以我做的是:

 ViewHolder holder = findViewHolderForPosition(0); if (holder != null) ((ParallaxRecyclerAdapter) getAdapter()).translateHeader(-holder.itemView.getTop() * 0.5f); 

为了测试这个,我添加了一个postDelayed Runnable,启动应用程序,滚动到最后,在0位置添加项目,然后再次向上滚动。 结果是:

在这里输入图像描述

如果有人正在寻找其他的视差效果,他们可以检查我的其他回购:

https://github.com/kanytu/android-parallax-listview

最简单的方法就是使用下面的onScrollListener而不依赖任何库。

 View view = recyclerView.getChildAt(0); if(view != null && recyclerView.getChildAdapterPosition(view) == 0) { view.setTranslationY(-view.getTop() / 2);// or use view.animate().translateY(); } 

确保你的第二个viewHolder项目有一个背景颜色来匹配抽屉/活动背景。 所以滚动看起来视差。

这个答案是为那些好奇的向GridLayoutManagerStaggeredGridLayoutManager添加一个视差标题

您需要将以下代码添加到适配器onBindViewHolderonCreateViewHolder

 StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams(); layoutParams.setFullSpan(true); 

对于kotlin,您可以如下配置回收站视图

 //setting parallax effects recyclerView.addOnScrollListener(object :RecyclerView.OnScrollListener(){ override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) val view = recyclerView?.getChildAt(0) if (view != null && recyclerView?.getChildAdapterPosition(view) === 0) { val imageView = view.findViewById(R.id.parallaxImage) imageView.translationY = -view.top / 2f } } })