Share
Embed
Eliminate RecyclerView Boilerplates
Layout and RecyclerView.ViewHolder binding which uses annotation processor to eliminate RecyclerView boilerplates for Android development.
ViewHolderBinding enables you to eliminate..
- switch or if-else statements for ViewType detection
- layout inflation boilerplate codes
- casting RecyclerView.ViewHolder class for binding layouts and ViewHolders
* GitHub repository
https://github.com/shaunkawano/ViewHolderBinding
* potatotips #37 (iOS/Android開発Tips共有会) - connpass https://potatotips.connpass.com/event/48618/
Shohei Kawano
February 15, 2017
Transcript
41 slides
-
RecyclerView.Adapter basic methods void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup
parent, int viewType) int getItemViewType(int position) int getItemCount() -
RecyclerView.Adapter basic methods void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup
parent, int viewType) int getItemViewType(int position) int getItemCount() -
@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 -
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.”); } } -
@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 -
@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ʜ -
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.”); } } -
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.”); } } -
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ʜ -
RecyclerView Boilerplates void onBindViewHolder(VH holder, int position) VH onCreateViewHolder(ViewGroup parent,
int viewType) ɾ*OTUBOUJBUFDVTUPN7JFX)PMEFSDMBTTCBTFEPOWJFX5ZQF ɾ0CUBJOWJFX5ZQFGSPNQPTJUJPO ɾ$BTU7JFX)PMEFSUPDVTUPN7JFX)PMEFSCBTFEPOQPTJUJPO -
@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() -
@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 -
@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 -
@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 -
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); } -
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 -
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 -
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)); } } } -
ɾGenerating codes using Annotation Processor is fun! ɾWe’ll keep using
RecyclerView for sure, so ɾLet us write less to do more! ·ͱΊ