Parallax header effect with RecyclerView

筅森魡賤 提交于 2019-12-17 22:16:19

问题


I want to change my ListView I currently have over to use RecyclerView so I can make use of StaggeredGridLayoutManager but RecyclerView does not have the ability to add a header like ListView.

Usually with a ListView I set an empty view in the header and put the image below the listview and translate the bottom image with the scrolling of the list to create the Parallax effect.

So with out a header how can I create the same parallax effect with RecyclerView?


回答1:


So today I tried to archive that effect on a RecyclerView. I was able to do it but since the code is too much I will paste here my github project and I will explain some of the key points of the project.

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

First we need to look at getItemViewType on the RecyclerView.Adapter class. This methods defines what type of view we're dealing with. That type will be passed on to onCreateViewHolder and there we can inflate different views. So what I did was: check if the position is the first one. If so then inflate the header, if not inflate a normal row.

I've added also a CustomRelativeLayout that clips the view so we don't have any trouble with the dividers and with the rows getting on top of the header.

From this point you seem to know the rest of the logic behind it.

The final result was:

EDIT:

If you need to insert something in adapter make sure you notify the correct position by adding 1 in the notifyItemChanged/Inserted method. For example:

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
}

Another important edit I've done is the scroll logic. The mCurrentOffset system I was using didn't work with the item insertion since the offset will change if you add an item. So what I did was:

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

To test this I added a postDelayed Runnable, started the app, scrolled to the end, add the item in position 0, and scroll up again. The result was:

If anyone is looking for other parallax effects they can check my other repo:

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




回答2:


the easiest way to do it, is using below onScrollListener without relying on any library.

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

make sure your second viewHolder item has a background color to match the drawer/activity background. so the scrolling looks parallax.




回答3:


For kotlin, you may config the recycler view as below

//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
            }
        }
    })



回答4:


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);


来源:https://stackoverflow.com/questions/26568087/parallax-header-effect-with-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!