我想更改我目前必须使用的 ListView,RecyclerView
以便我可以使用,StaggeredGridLayoutManager
但 RecyclerView 无法添加像 ListView 这样的标题。
通常使用 ListView 我在标题中设置一个空视图并将图像放在列表视图下方,并通过滚动列表来转换底部图像以创建Parallax
效果。
因此,如果没有标题,我如何创建相同的视差效果RecyclerView
?
我想更改我目前必须使用的 ListView,RecyclerView
以便我可以使用,StaggeredGridLayoutManager
但 RecyclerView 无法添加像 ListView 这样的标题。
通常使用 ListView 我在标题中设置一个空视图并将图像放在列表视图下方,并通过滚动列表来转换底部图像以创建Parallax
效果。
因此,如果没有标题,我如何创建相同的视差效果RecyclerView
?
最简单的方法是使用下面onScrollListener
而不依赖任何库。
View view = recyclerView.getChildAt(0);
if(view != null && recyclerView.getChildAdapterPosition(view) == 0) {
view.setTranslationY(-view.getTop() / 2);// or use view.animate().translateY();
}
确保您的第二个viewHolder
项目具有与抽屉/活动背景相匹配的背景颜色。所以滚动看起来有视差。
所以今天我试图将这种效果存档到RecyclerView
. 我能够做到,但是由于代码太多,我将在这里粘贴我的 github 项目,并解释该项目的一些关键点。
https://github.com/kanytu/android-parallax-recyclerview
首先我们需要看一下getItemViewType
类RecyclerView.Adapter
。这个方法定义了我们正在处理的视图类型。该类型将被传递到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,然后再次向上滚动。结果是:
如果有人正在寻找其他视差效果,他们可以查看我的其他 repo:
对于 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
}
}
})
This answer is for those curious about adding a parallax header to a GridLayoutManager
or a StaggeredGridLayoutManager
You'll want to add the following code to your adapter in either onBindViewHolder
or onCreateViewHolder
StaggeredGridLayoutManager.LayoutParams layoutParams =
(StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);