Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallax header effect with RecyclerView

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?

like image 232
tyczj Avatar asked Oct 25 '14 22:10

tyczj


2 Answers

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.

like image 92
Kosh Avatar answered Oct 10 '22 07:10

Kosh


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:

enter image description here

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:

enter image description here

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

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

like image 33
Pedro Oliveira Avatar answered Oct 10 '22 08:10

Pedro Oliveira