Recyclerview in Action
Kulina - PT Jejaring Makanan Indonesia
@pratamawijaya
#TechTalk8
9
./whoami
Pratama Nur Wijaya
Android Coder since 2012, usually active at GDG
Jogjakarta event, Yogyakarta Android Community and ID-
Android
Favorite Android Library : Square Library FTW!! and
RxAndroid X RxJava
Recomendation Blog: YKode, blog.danlew.net,
bignerdranch.com
Join our force
Send your cv and linkedin profile to pratama@kulina.id and may the
force be with u
Kulina is Hiring Android Developer
Recyclerview ?
“Recyclerview is a view group that
displays a list of scrollable items”
Listview
Why Google ?
- Listview codebase so complex
- Duplicate functionality
- Itemclicklistener vs onClickListener
- Hard to create animation
- And others (Google IO 2016)
https://www.youtube.com/watch?v=LqBlYJTfLP4
Why Google ?
Setup Recyclerview
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0' // recyclerview-v7
}
1. app/build.gradle
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
2. Layout
RecyclerView Component
RecyclerView
Layout Manager Item AnimatorAdapter Item Decoration
Positioning
View
Animating
View
Decorate
Item
Provide
View
Layout Manager
LinearLayoutManager
layoutManagerVertical = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManagerVertical);
layoutManagerHorizontal =
new LinearLayoutManager(context, LinearLayoutManager.
HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManagerHorizontal);
GridlayoutManager
gridLayoutManager = new GridLayoutManager(context, SPAN_COUNT);
recyclerView.setLayoutManager(gridLayoutManager);
StaggeredLayoutManager
gridLayoutManager = new StaggeredGridLayoutManager(2,
StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(gridLayoutManager);
Multitype Item Layout
Adapter
- Create View and Viewholder
- Bind item to ViewHolder
- Notify Recyclerview about changes
- Item Interaction handling (click, etc)
- Multiple view types
Adapter Component
public class LinearLayoutAdapter extends RecyclerView.Adapter<LinearLayoutAdapter.
LinearLayoutViewHolder>{
@Override public LinearLayoutViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override public void onBindViewHolder(LinearLayoutViewHolder holder, int position) {}
@Override public int getItemCount() {return 0;}
public class LinearLayoutViewHolder extends RecyclerView.ViewHolder{
public LinearLayoutViewHolder(View itemView) { super(itemView); }
}
}
Sample Adapter Clas
Viewholder Class
public class LinearHolder extends RecyclerView.ViewHolder {
@BindView(R.id.img) ImageView img;
@BindView(R.id.name) TextView name;
@BindView(R.id.location) TextView location;
public LinearHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bindItem(Mountain mountain) {
name.setText(mountain.name);
location.setText(mountain.location);
ImageLoader.loadImage(context, img, mountain.img);
}
}
Create View and Bind View
@Override public LinearHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new LinearHolder(
LayoutInflater.from(context).inflate(R.layout.item_linear_vertical, parent, false));
}
@Override public void onBindViewHolder(LinearHolder holder, int position) {
if (mountainList != null && mountainList.size() > 0) {
holder.bindItem(mountainList.get(position));
}
}
Handle Click Listener
Create interface
public interface ClickListener {
void onItemClick(int pos);
}
Pass Listener into Adapter
public interface ClickListener {
void onItemClick(int pos);
}
private Context context;
private List<String> strings;
private ClickListener listener;
public TextAdapter(Context context, List<String> strings, ClickListener listener) {
this.context = context;
this.strings = strings;
this.listener = listener;
}
Set Clicklistener at ViewHolder
public class MainHolder extends RecyclerView.ViewHolder {
@BindView(R.id.txt_title) TextView txtTitle;
@BindView(R.id.container_text) LinearLayout container;
public MainHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bindData(String string, final int pos) {
txtTitle.setText("" + string);
container.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
listener.onItemClick(pos);
}
});
}
}
Implement Listener into Activity/Fragment
public class HomeFragment extends Fragment implements TextAdapter.ClickListener{
// rest fragment class
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
adapter = new TextAdapter(getActivity(), listMenu, this);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
}
@Override public void onItemClick(int pos) {
// do something
}
}
Item Decoration
Simple Item Decoration
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
public SimpleDividerItemDecoration(Context context) {
mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
}
@Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}}}
Simple Item Decoration
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
Item Animator
Simple Item Animator
recyclerView.setItemAnimator(new DefaultItemAnimator());
Other item animator ?
Take a look
https://github.com/wasabeef/recyclerview-animators ?;)
Multitype Viewholder
Multiviewtype Holder
@Override public int getItemViewType(int position) {
if (position == 0) {
return VIEW_TYPE_HEADER;
} else {
return VIEW_TYPE_ITEM;
}
}
@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == VIEW_TYPE_HEADER) {
HeaderAdapterHolder headerHolder = (HeaderAdapterHolder) holder;
}else if (holder.getItemViewType() == VIEW_TYPE_ITEM) {
ItemAdapterHolder itemHolder = (ItemAdapterHolder) holder;
}
}
http://hannesdorfmann.com/android/adapter-delegates
https://github.com/sockeqwe/AdapterDelegates
Do you found adapter hell ?
Take a look these awesome article
Reference
- Dave Smith ~ Mastering Recyclerview http://www.slideshare.
net/devunwired/mastering-recyclerview-layouts
- Google I/O 2016 ~ https://www.youtube.com/watch?v=LqBlYJTfLP4
- BignerdRanch https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals-
for-listview-experts/
- http://hannesdorfmann.com/android/adapter-delegates
- May Google be with you
Thanks

Recyclerview in action

  • 1.
    Recyclerview in Action Kulina- PT Jejaring Makanan Indonesia @pratamawijaya #TechTalk8 9
  • 2.
    ./whoami Pratama Nur Wijaya AndroidCoder since 2012, usually active at GDG Jogjakarta event, Yogyakarta Android Community and ID- Android Favorite Android Library : Square Library FTW!! and RxAndroid X RxJava Recomendation Blog: YKode, blog.danlew.net, bignerdranch.com
  • 3.
  • 4.
    Send your cvand linkedin profile to pratama@kulina.id and may the force be with u Kulina is Hiring Android Developer
  • 5.
  • 6.
    “Recyclerview is aview group that displays a list of scrollable items”
  • 7.
  • 8.
  • 9.
    - Listview codebaseso complex - Duplicate functionality - Itemclicklistener vs onClickListener - Hard to create animation - And others (Google IO 2016) https://www.youtube.com/watch?v=LqBlYJTfLP4 Why Google ?
  • 10.
    Setup Recyclerview dependencies { compile'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:design:23.4.0' // recyclerview-v7 } 1. app/build.gradle <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" /> 2. Layout
  • 11.
    RecyclerView Component RecyclerView Layout ManagerItem AnimatorAdapter Item Decoration Positioning View Animating View Decorate Item Provide View
  • 12.
  • 13.
    LinearLayoutManager layoutManagerVertical = newLinearLayoutManager(context); recyclerView.setLayoutManager(layoutManagerVertical); layoutManagerHorizontal = new LinearLayoutManager(context, LinearLayoutManager. HORIZONTAL, false); recyclerView.setLayoutManager(layoutManagerHorizontal);
  • 14.
    GridlayoutManager gridLayoutManager = newGridLayoutManager(context, SPAN_COUNT); recyclerView.setLayoutManager(gridLayoutManager);
  • 15.
    StaggeredLayoutManager gridLayoutManager = newStaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(gridLayoutManager);
  • 16.
  • 17.
  • 18.
    - Create Viewand Viewholder - Bind item to ViewHolder - Notify Recyclerview about changes - Item Interaction handling (click, etc) - Multiple view types Adapter Component
  • 19.
    public class LinearLayoutAdapterextends RecyclerView.Adapter<LinearLayoutAdapter. LinearLayoutViewHolder>{ @Override public LinearLayoutViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(LinearLayoutViewHolder holder, int position) {} @Override public int getItemCount() {return 0;} public class LinearLayoutViewHolder extends RecyclerView.ViewHolder{ public LinearLayoutViewHolder(View itemView) { super(itemView); } } } Sample Adapter Clas
  • 20.
    Viewholder Class public classLinearHolder extends RecyclerView.ViewHolder { @BindView(R.id.img) ImageView img; @BindView(R.id.name) TextView name; @BindView(R.id.location) TextView location; public LinearHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public void bindItem(Mountain mountain) { name.setText(mountain.name); location.setText(mountain.location); ImageLoader.loadImage(context, img, mountain.img); } }
  • 21.
    Create View andBind View @Override public LinearHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new LinearHolder( LayoutInflater.from(context).inflate(R.layout.item_linear_vertical, parent, false)); } @Override public void onBindViewHolder(LinearHolder holder, int position) { if (mountainList != null && mountainList.size() > 0) { holder.bindItem(mountainList.get(position)); } }
  • 22.
  • 23.
    Create interface public interfaceClickListener { void onItemClick(int pos); }
  • 24.
    Pass Listener intoAdapter public interface ClickListener { void onItemClick(int pos); } private Context context; private List<String> strings; private ClickListener listener; public TextAdapter(Context context, List<String> strings, ClickListener listener) { this.context = context; this.strings = strings; this.listener = listener; }
  • 25.
    Set Clicklistener atViewHolder public class MainHolder extends RecyclerView.ViewHolder { @BindView(R.id.txt_title) TextView txtTitle; @BindView(R.id.container_text) LinearLayout container; public MainHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public void bindData(String string, final int pos) { txtTitle.setText("" + string); container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { listener.onItemClick(pos); } }); } }
  • 26.
    Implement Listener intoActivity/Fragment public class HomeFragment extends Fragment implements TextAdapter.ClickListener{ // rest fragment class @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ButterKnife.bind(this, view); adapter = new TextAdapter(getActivity(), listMenu, this); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); } @Override public void onItemClick(int pos) { // do something } }
  • 27.
  • 28.
    Simple Item Decoration publicclass SimpleDividerItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; public SimpleDividerItemDecoration(Context context) { mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); }}}
  • 29.
    Simple Item Decoration recyclerView.addItemDecoration(newSimpleDividerItemDecoration(getActivity()));
  • 30.
  • 31.
  • 32.
    Other item animator? Take a look https://github.com/wasabeef/recyclerview-animators ?;)
  • 33.
  • 34.
    Multiviewtype Holder @Override publicint getItemViewType(int position) { if (position == 0) { return VIEW_TYPE_HEADER; } else { return VIEW_TYPE_ITEM; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder.getItemViewType() == VIEW_TYPE_HEADER) { HeaderAdapterHolder headerHolder = (HeaderAdapterHolder) holder; }else if (holder.getItemViewType() == VIEW_TYPE_ITEM) { ItemAdapterHolder itemHolder = (ItemAdapterHolder) holder; } }
  • 35.
  • 36.
    Reference - Dave Smith~ Mastering Recyclerview http://www.slideshare. net/devunwired/mastering-recyclerview-layouts - Google I/O 2016 ~ https://www.youtube.com/watch?v=LqBlYJTfLP4 - BignerdRanch https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals- for-listview-experts/ - http://hannesdorfmann.com/android/adapter-delegates - May Google be with you
  • 37.