Skip to content

Instantly share code, notes, and snippets.

@morgotth
Last active October 26, 2019 14:12
Show Gist options
  • Save morgotth/16b8664e1b9928df1640 to your computer and use it in GitHub Desktop.
Save morgotth/16b8664e1b9928df1640 to your computer and use it in GitHub Desktop.
Recycled Pager Adapter inspired by RecyclerView
package com.example;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.Foo;
import com.example.RecycledPagerAdapter;
public class FooAdapter extends RecycledPagerAdapter<FooViewHolder> {
private List<Foo> data;
private LayoutInflater layoutInflater;
@Override
public FooViewHolder onCreateViewHolder(ViewGroup parent) {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
// Inflate view
View v = layoutInflater.inflate(R.layout.item_player_card, parent, false);
// Return view holder
return new FooViewHolder(v);
}
@Override
public void onBindViewHolder(FooViewHolder viewHolder, int position) {
// Show foo inside viewHolder
viewHolder.show(data.get(position));
}
@Override
public int getCount() {
return data == null ? 0 : data.size();
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
// TODO: optional callback when current object has changed
}
public TrackSet getData() {
return data;
}
public void setData(TrackSet data) {
if (this.data != data) {
this.data = data;
notifyDataSetChanged();
}
}
public static class FooViewHolder extends RecycledPagerAdapter.ViewHolder {
public FooViewHolder(View v) {
super(v);
// TODO: use findViewById or Butterknife
}
public void show(Foo foo) {
// TODO: update views with foo
}
}
}
package com.example;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import com.example.RecycledPagerAdapter.ViewHolder;
import java.util.LinkedList;
import java.util.Queue;
/**
* See https://gist.github.com/tvkkpt/2e667cb707859123b422
* @param <VH>
*/
public abstract class RecycledPagerAdapter<VH extends ViewHolder> extends PagerAdapter {
public static abstract class ViewHolder {
final View itemView;
public ViewHolder(View itemView) {
this.itemView = itemView;
}
}
Queue<VH> destroyedItems = new LinkedList<>();
@Override
public final Object instantiateItem(ViewGroup container, int position) {
VH viewHolder = destroyedItems.poll();
if (viewHolder != null) {
// Re-add existing view before rendering so that we can make change inside getView()
container.addView(viewHolder.itemView);
onBindViewHolder(viewHolder, position);
} else {
viewHolder = onCreateViewHolder(container);
onBindViewHolder(viewHolder, position);
container.addView(viewHolder.itemView);
}
return viewHolder;
}
@Override
public final void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(((VH) object).itemView);
destroyedItems.add((VH) object);
}
@Override
public final boolean isViewFromObject(View view, Object object) {
return ((VH) object).itemView == view;
}
/**
* Create a new view holder
* @param parent
* @return view holder
*/
public abstract VH onCreateViewHolder(ViewGroup parent);
/**
* Bind data at position into viewHolder
* @param viewHolder
* @param position
*/
public abstract void onBindViewHolder(VH viewHolder, int position);
}
@jt-gilkeson
Copy link

jt-gilkeson commented Nov 21, 2017

A small problem with FooAdapter is rotations - the code that saves the layout inflater breaks after a rotation (using old context)
(i.e. the items are inflated with the wrong context - so if you use an item's context in onBindViewHolder it can cause problems - like if you use the context of an imageView with Glide to load an image)

Here's a fix:

if (layoutInflater == null || layoutInflater.getContext() != parent.getContext())

@snehazanzane
Copy link

The Best Solution. Because of this solution view pager animation is working very fast and smooth.
Thanks Morgotth 👍

@dariadobsai
Copy link

Hi Morgotth,

Thank you for your solution:)

I wonder if there is a way to set the items inside the this view pager onClickListener?
I was searching but cannot find anything that would work for me

@morgotth
Copy link
Author

Hi DariaKalashnik,

I think it's possible but I would better advise using ViewPager 2,
based on RecyclerView and so better fondations 👍

BTW thx to other comments, happy this gist could help you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment