Slide 1

Slide 1 text

ELIMINATE RECYCLERVIEW BOILERPLATES ΁͍΁͍ @shaunkawano גࣜձࣾτϧς / Android Developer

Slide 2

Slide 2 text

Shohei Kawano @shaunkawano Android Developer at Torte, Inc. About Me

Slide 3

Slide 3 text

Let’s talk about RecyclerView

Slide 4

Slide 4 text

When you use RecyclerView, you need to implement RecyclerView.Adapter

Slide 5

Slide 5 text

RecyclerView.Adapter basic methods

Slide 6

Slide 6 text

RecyclerView.Adapter basic methods void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup parent, int viewType) int getItemViewType(int position) int getItemCount()

Slide 7

Slide 7 text

RecyclerView.Adapter basic methods void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup parent, int viewType) int getItemViewType(int position) int getItemCount()

Slide 8

Slide 8 text

Let’s assume we have R.layout.id as our view type.

Slide 9

Slide 9 text

onCreateViewHolder

Slide 10

Slide 10 text

@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); switch (viewType) { case R.layout.row_taro:
 View taroView = inflater.inflate(R.layout.row_taro, parent, false);
 return new TaroViewHolder(taroView);
 case R.layout.row_shiro:
 View shiroView = inflater.inflate(R.layout.row_shiro, parent, false);
 return new ShiroViewHolder(shiroView);
 case R.layout.row_leona:
 View leonaView = inflater.inflate(R.layout.row_leona, parent, false);
 return new LeonaViewHolder(leonaView);
 default:
 throw new IllegalArgumentException(“error message here.”);
 }
 } onCreateViewHolder

Slide 11

Slide 11 text

onBindViewHolder

Slide 12

Slide 12 text

onBindViewHolder @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona:
 onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } }

Slide 13

Slide 13 text

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona:
 onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } } onBindViewHolder

Slide 14

Slide 14 text

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona:
 onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } } onBindViewHolder 8FOFFEUPDBTUʜ

Slide 15

Slide 15 text

getItemViewType

Slide 16

Slide 16 text

getItemViewType %FQFOEJOHPOIPXZPVJNQMFNFOUJU

Slide 17

Slide 17 text

Let’s see the overview.

Slide 18

Slide 18 text

RecyclerView.Adapter Overview @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona: onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); switch (viewType) { case R.layout.row_taro:
 View taroView = inflater.inflate(R.layout.row_taro, parent, false);
 return new TaroViewHolder(taroView);
 case R.layout.row_shiro:
 View shiroView = inflater.inflate(R.layout.row_shiro, parent, false);
 return new ShiroViewHolder(shiroView);
 case R.layout.row_leona:
 View leonaView = inflater.inflate(R.layout.row_leona, parent, false);
 return new LeonaViewHolder(leonaView);
 default:
 throw new IllegalArgumentException(“error message here.”);
 }
 }

Slide 19

Slide 19 text

RecyclerView.Adapter Overview @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona: onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); switch (viewType) { case R.layout.row_taro:
 View taroView = inflater.inflate(R.layout.row_taro, parent, false);
 return new TaroViewHolder(taroView);
 case R.layout.row_shiro:
 View shiroView = inflater.inflate(R.layout.row_shiro, parent, false);
 return new ShiroViewHolder(shiroView);
 case R.layout.row_leona:
 View leonaView = inflater.inflate(R.layout.row_leona, parent, false);
 return new LeonaViewHolder(leonaView);
 default:
 throw new IllegalArgumentException(“error message here.”);
 }
 }

Slide 20

Slide 20 text

RecyclerView.Adapter Overview @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int viewType = getItemViewType(position);
 switch (viewType) { case R.layout.row_taro:
 onBindTaroViewHolder((TaroViewHolder) holder, position); break; case R.layout.row_shiro:
 onBindShiroViewHolder((ShiroViewHolder) holder, position); break; case R.layout.row_leona: onBindLeonaViewHolder((LeonaViewHolder) holder, position); break;
 default:
 throw new IllegalArgumentException(“Some message.”);
 } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); switch (viewType) { case R.layout.row_taro:
 View taroView = inflater.inflate(R.layout.row_taro, parent, false);
 return new TaroViewHolder(taroView);
 case R.layout.row_shiro:
 View shiroView = inflater.inflate(R.layout.row_shiro, parent, false);
 return new ShiroViewHolder(shiroView);
 case R.layout.row_leona:
 View leonaView = inflater.inflate(R.layout.row_leona, parent, false);
 return new LeonaViewHolder(leonaView);
 default:
 throw new IllegalArgumentException(“error message here.”);
 }
 } #PJMFSQMBUFTʜ

Slide 21

Slide 21 text

RecyclerView Boilerplates void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup parent, int viewType) ɾ*OTUBOUJBUFDVTUPN7JFX)PMEFSDMBTTCBTFEPOWJFX5ZQF ɾ0CUBJOWJFX5ZQFGSPNQPTJUJPO ɾ$BTU7JFX)PMEFSUPDVTUPN7JFX)PMEFSCBTFEPOQPTJUJPO

Slide 22

Slide 22 text

YES WE WANT TO ELIMINATE THEM.

Slide 23

Slide 23 text

LET’S GENERATE THEM INSTEAD OF WRITING THEM.

Slide 24

Slide 24 text

PREREQUISITES

Slide 25

Slide 25 text

1. Implement getItemViewType

Slide 26

Slide 26 text

@Override public int getItemViewType(int position) {
 switch (CatType.of(position)) {
 case TARO:
 return R.layout.row_taro;
 case SHIRO:
 return R.layout.row_shiro;
 case LEONA:
 return R.layout.row_leona;
 default:
 throw new IllegalArgumentException(“Some message.”);
 }
 } Implement RecyclerView.Adapter#getItemViewType()

Slide 27

Slide 27 text

@Override public int getItemViewType(int position) {
 switch (CatType.of(position)) {
 case TARO:
 return R.layout.row_taro;
 case SHIRO:
 return R.layout.row_shiro;
 case LEONA:
 return R.layout.row_leona;
 default:
 throw new IllegalArgumentException(“Some message.”);
 }
 } Implement RecyclerView.Adapter#getItemViewType() Return R.layout.id as view type

Slide 28

Slide 28 text

2. Add annotations @AdapterBinding @ViewHolder @OnBind

Slide 29

Slide 29 text

@AdapterBinding public class CatAdapter extends RecyclerView.Adapter { … } @ViewHolder(layout = R.layout.row_title) static class TitleViewHolder extends RecyclerView.ViewHolder {
 TitleViewHolder(View itemView) {
 super(itemView);
 } 
 
 @OnBind void onBind() {
 // bind layouts
 }
 … Add @AdapterBinding ,@ViewHolder, @OnBind (optional) annotations

Slide 30

Slide 30 text

@AdapterBinding public class CatAdapter extends RecyclerView.Adapter { … } @ViewHolder(layout = R.layout.row_title) static class TitleViewHolder extends RecyclerView.ViewHolder {
 TitleViewHolder(View itemView) {
 super(itemView);
 } 
 
 @OnBind void onBind() {
 // bind layouts
 }
 … Add @AdapterBinding ,@ViewHolder, @OnBind (optional) annotations Add on RecyclerView.Adapter Add on RecyclerView.ViewHolder Add on inner methods within RecyclerView.ViewHolder

Slide 31

Slide 31 text

3. Rebuild Project

Slide 32

Slide 32 text

4. Call generated methods

Slide 33

Slide 33 text

Call static methods within generated class @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { CatAdapterViewHolderBinding.bindViewHolder(this, holder, position); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); return CatAdapterViewHolderBinding.createViewHolder(inflater, parent, viewType); }

Slide 34

Slide 34 text

Call static methods within generated class @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { CatAdapterViewHolderBinding.bindViewHolder(this, holder, position); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); return CatAdapterViewHolderBinding.createViewHolder(inflater, parent, viewType); } Adapter໊ʴViewHolderBinding.bindViewHolder Adapter໊ʴViewHolderBinding.bindViewHolder.createViewHolder

Slide 35

Slide 35 text

Let’s take a look at generated source codes.

Slide 36

Slide 36 text

class CatAdapterViewHolderBinding { public static ViewHolder createViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) { switch (viewType) { case 2130968636: View TaroViewHolderView = inflater.inflate(2130968636, parent, false); return new CatAdapter.TaroViewHolder(TaroViewHolderView); case 2130968635: View ShiroViewHolderView = inflater.inflate(2130968635, parent, false); return new CatAdapter.ShiroViewHolder(ShiroViewHolderView); case 2130968634: View LeonaViewHolderView = inflater.inflate(2130968634, parent, false); return new CatAdapter.LeonaViewHolder(LeonaViewHolderView); case 2130968637: View TitleViewHolderView = inflater.inflate(2130968637, parent, false); return new CatAdapter.TitleViewHolder(TitleViewHolderView); default: throw new IllegalArgumentException(String.format(Locale.US, "Illegal viewType(%d) passed to CatAdapter.", viewType)); } } Generated method: createViewHolder

Slide 37

Slide 37 text

Generated method: bindViewHolder public static void bindViewHolder(Adapter adapter, ViewHolder holder, int position) { int viewType = adapter.getItemViewType(position); switch (viewType) { case 2130968636: ((CatAdapter.TaroViewHolder) holder).onBind(); break; case 2130968635: ((CatAdapter.ShiroViewHolder) holder).onBind(); break; case 2130968634: ((CatAdapter.LeonaViewHolder) holder).onBind(position); break; case 2130968637: ((CatAdapter.TitleViewHolder) holder).onBind(); break; default: throw new IllegalArgumentException(String.format(Locale.US, "Illegal viewType(%d) passed to CatAdapter.", viewType)); } } }

Slide 38

Slide 38 text

ViewHolderBinding IUUQTHJUIVCDPNTIBVOLBXBOP7JFX)PMEFS#JOEJOH

Slide 39

Slide 39 text

Conclusion

Slide 40

Slide 40 text

ɾGenerating codes using Annotation Processor is fun! ɾWe’ll keep using RecyclerView for sure, so ɾLet us write less to do more! ·ͱΊ

Slide 41

Slide 41 text

THANK YOU ! ΁͍΁͍ @shaunkawano גࣜձࣾτϧς / Android Developer