既然已经对 ViewBinding一知半解 ,那么接下来肯定是要集成到项目中跑起来,所以此篇主讲关于ViewBinding集成在基类的具体方式~

兄弟篇

  • 组件化之路 - ViewBinding一知半解
  • 组件化之路 - ViewBinding基类封装

我看了看网上关于ViewBinding基类集成,一般都是通过反射非反射的方法去集成基类,进行使用的 > <

我自己稍作总结后,得出以下结论,通篇也以此结论进行说明

关于ViewBinding基类集成,主要集成有俩种方式

  • 常规写法,手动通过原始代码封装Base基类,达到基类封装效果,从而运用到自己的项目
  • 三方框架,如加入 ViewBindingKTX 框架,包体积虽有增大,但作者能解决一些自己后续会遇到或忽略的问题 (起初是我朋友推荐,后来在知乎看到了原作者也在推荐)

关于ViewBinding基类集成,主要集成有俩种用法

  • 非反射(不使用反射,常规写法)
  • 反射(如果代码混淆的话,容易出现找不到类的场景)

关于ViewBinding基类集成,主要集成有俩种开发语言

  • Java
  • Kotlin

因为我用Kotlin经验还不足,所以我自己写了一下Java - BaseActivity基类封装 ~

  • 常规集成(不使用反射)
    • Java - BaseActivity
    • Kotlin - BaseActivity
    • Kotlin - BaseFragment
  • 反射集成
    • Java - BaseActivity
    • Java - BaseFragment
    • Kotlin - BaseActivity
    • Kotlin - BaseFragment
  • 三方框架
    • Feature
    • 基础配置
    • Java改造基类
      • 不使用反射
      • 反射

常规集成(不使用反射)

关于ViewBinding基类封装的很多知识,借鉴了此篇 blog 的尾部代码(当然,这类型代码太常见了,至少我看到多篇相似的封装方式,不过一点儿都不影响我的学习热情,加油 ) ~

Java - BaseActivity

这种方式,也是我在项目中使用的方式,经本人亲自尝试,可用 ~ 但要注意ViewBinding在不同场景的使用方式有所不同,此处仅作用于Activity相关组件, 如不懂可前往ViewBinding继续进阶 ~

//基类封装
public abstract class BaseBindingActivity<T extends ViewBinding>  extends AppCompatActivity {private T mBinding;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mBinding = getViewBinding();setContentView(mBinding.getRoot());}public abstract T getViewBinding();
}//使用方式
public class MainActivity extends AppCompatActivity {private ActivityMainBinding mBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mBinding.textView.text = "冲刺把,卡布达~"}@Overridepublic ViewBinding getViewBinding() {mBinding = ActivityMainBinding.inflate(getLayoutInflater());return mBinding;}
}
Kotlin - BaseActivity
//基类封装
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {private lateinit var _binding: Tprotected val binding get() = _binding;override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)_binding = getViewBinding()setContentView(_binding.root)}protected abstract fun getViewBinding(): T
}//使用方式
class MainActivity : BaseActivity<ActivityMainBinding>() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding.textView.text = "这是MainActivity"}override fun getViewBinding() = ActivityMainBinding.inflate(layoutInflater)
}
Kotlin - BaseFragment
//基类封装
abstract class BaseFragment<T : ViewBinding> : Fragment() {private lateinit var _binding: Tprotected val binding get() = _binding;override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {_binding = getViewBinding(inflater, container)return _binding.root}protected abstract fun getViewBinding(inflater: LayoutInflater, container: ViewGroup?): T
}//使用方式
class FirstFragment : BaseFragment<FragmentFirstBinding>() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)binding.textView.text = "这是FirstFragment"}override fun getViewBinding(inflater: LayoutInflater,container: ViewGroup?) = FragmentFirstBinding.inflate(inflater, container, false)
}

反射集成

不推荐使用,会有混淆问题

Java - BaseActivity
//基类封装
public class BaseActivity<T extends ViewBinding> extends AppCompatActivity {protected T viewBinding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();Class cls = (Class) type.getActualTypeArguments()[0];try {Method inflate = cls.getDeclaredMethod("inflate", LayoutInflater.class);viewBinding = (T) inflate.invoke(null, getLayoutInflater());setContentView(viewBinding.getRoot());} catch (NoSuchMethodException | IllegalAccessException| InvocationTargetException e) {e.printStackTrace();}}
}//使用方式
public class MainActivity extends BaseActivity<ActivityMainBinding> {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);viewBinding.button.setText("这是 MainActivity ViewBinding");viewBinding.button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Log.d("MainView","点击按钮");}});}
}
Java - BaseFragment
//基类封装
public class BaseFragment<T extends ViewBinding> extends Fragment {protected T viewBinding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();Class cls = (Class) type.getActualTypeArguments()[0];try {Method inflate = cls.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);viewBinding = (T) inflate.invoke(null, inflater, container, false);}  catch (NoSuchMethodException | IllegalAccessException| InvocationTargetException e) {e.printStackTrace();}return viewBinding.getRoot();}
}//使用方式
public class MainFragment extends BaseFragment<FragmentMainBinding>{@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);viewBinding.button.setText("这是 MainFragment ViewBinding");viewBinding.button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Log.d("MainView","点击按钮");}});}
}
Kotlin - BaseActivity
//基类封装
open class BaseActivity<T : ViewBinding> : AppCompatActivity() {protected lateinit var binding: Toverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val type = javaClass.genericSuperclass as ParameterizedTypeval aClass = type.actualTypeArguments[0] as Class<*>val method = aClass.getDeclaredMethod("inflate", LayoutInflater::class.java)binding = method.invoke(null, layoutInflater) as TsetContentView(binding.root)}
}//使用方式
class MainActivity : BaseActivity<ActivityMainBinding>() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding.textView.text = "这是MainActivity"}
}
Kotlin - BaseFragment
//基类封装
open class BaseFragment<T:ViewBinding>:Fragment(){lateinit var binding: Toverride fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {val type = javaClass.genericSuperclass as ParameterizedTypeval aClass = type.actualTypeArguments[0] as Class<*>val method = aClass.getDeclaredMethod("inflate", LayoutInflater::class.java,ViewGroup::class.java,Boolean::class.java)binding = method.invoke(null,layoutInflater,container,false) as Treturn binding.root}
}//使用方式
class FirstFragment : BaseFragment<FragmentFirstBinding>() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)binding.textView.text = "这是FirstFragment"}
}

三方框架

这里使用的主要是 ViewBindingKTX 框架,此处仅介绍简单的使用方式,如有具体需求,可前往原作者的 Github ~

以下部分基本都是copy的原作者,实属无聊,权当记录把...

Feature
  • 支持 Kotlin 和 Java 用法
  • 支持多种使用反射和不使用反射的用法
  • 支持封装改造自己的基类,使其用上 ViewBinding
  • 支持 BaseRecyclerViewAdapterHelper
  • 支持 Activity、Fragment、Dialog、Adapter
  • 支持在 Fragment 自动释放绑定类的实例对象
  • 支持实现自定义组合控件
  • 支持 TabLayout 实现自定义标签布局
  • 支持 NavigationView 设置头部控件
  • 支持 DataBinding 自动设置 lifecycleOwner
基础配置

build(project)

allprojects {repositories {...maven { url 'https://www.jitpack.io' }}
}

build(app)

android {buildFeatures {viewBinding = true}
}dependencies {// 以下都是可选,请根据需要进行添加implementation 'com.github.DylanCaiCoding.ViewBindingKTX:viewbinding-ktx:1.2.4'implementation 'com.github.DylanCaiCoding.ViewBindingKTX:viewbinding-nonreflection-ktx:1.2.4'implementation 'com.github.DylanCaiCoding.ViewBindingKTX:viewbinding-base:1.2.4'implementation 'com.github.DylanCaiCoding.ViewBindingKTX:viewbinding-brvah:1.2.4'
}
Java改造基类

因对于Kotlin还不熟,所以仅copy - Java改造基类做个记录,有需要看Ktolin改造基类的话, 直接跳这里看Ktolin封装的基类把 ~

不使用反射

Activity

public abstract class BaseBindingActivity<VB extends ViewBinding> extends AppCompatActivity {private VB binding;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = onCreateViewBinding(getLayoutInflater());setContentView(binding.getRoot());}protected abstract VB onCreateViewBinding(@NonNull LayoutInflater layoutInflater);public VB getBinding() {return binding;}
}//使用方式
public class MainActivity extends BaseBindingActivity<ActivityMainBinding> {@Overrideprotected ActivityMainBinding onCreateViewBinding(@NonNull LayoutInflater layoutInflater) {return ActivityMainBinding.inflate(layoutInflater);}@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);getBinding().getTvHelloWord().setText("Hello Android!");}
}

Fragment

public abstract class BaseBindingFragment<VB extends ViewBinding> extends Fragment {private VB binding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = onCreateViewBinding(inflater, container);return binding.getRoot();}@Overridepublic void onDestroyView() {super.onDestroyView();binding = null;}public VB getBinding() {return binding;}protected abstract VB onCreateViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent);
}//使用方式
public class HomeFragment extends BaseBindingFragment<FragmentHomeBinding> {@Overrideprotected FragmentHomeBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent) {return FragmentHomeBinding.inflate(inflater, parent, false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);getBinding().getTvHelloWord().setText("Hello Android!");}
}

Adapter

public abstract class BaseBindingQuickAdapter<T, VB extends ViewBinding>extends BaseQuickAdapter<T, BaseBindingQuickAdapter.BaseBindingHolder> {public BaseBindingQuickAdapter() {this(-1);}public BaseBindingQuickAdapter(@LayoutRes int layoutResId) {super(-layoutResId);}@NotNull@Overrideprotected BaseBindingHolder onCreateDefViewHolder(@NotNull ViewGroup parent, int viewType) {return new BaseBindingHolder(onCreateViewBinding(LayoutInflater.from(parent.getContext()), parent));}protected abstract VB onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent);public static class BaseBindingHolder extends BaseViewHolder {private final ViewBinding binding;public BaseBindingHolder(@NotNull View view) {this(() -> view);}public BaseBindingHolder(@NotNull ViewBinding binding) {super(binding.getRoot());this.binding = binding;}@NonNull@SuppressWarnings("unchecked")public <VB extends ViewBinding> VB getViewBinding() {return (VB) binding;}}
}//使用方式
public class FooAdapter extends BaseBindingQuickAdapter<Foo, ItemFooBinding> {@Overrideprotected ItemFooBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {return ItemFooBinding.inflate(inflater, parent, false);}@Overrideprotected void convert(@NotNull BaseBindingHolder holder, Foo item) {ItemFooBinding binding = holder.getViewBinding();binding.tvFoo.setText(item.getValue());}
}

MultiType

public abstract class BindingViewDelegate<T, VB extends ViewBinding> extendsItemViewDelegate<T, BindingViewDelegate.BindingViewHolder<VB>> {@NotNull@Overridepublic BindingViewHolder<VB> onCreateViewHolder(@NotNull Context context, @NotNull ViewGroup parent) {return new BindingViewHolder<>(onCreateViewBinding(LayoutInflater.from(parent.getContext()), parent));}protected abstract VB onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent);public static class BindingViewHolder<VB extends ViewBinding> extends RecyclerView.ViewHolder {private final VB binding;public BindingViewHolder(@NonNull VB binding) {super(binding.getRoot());this.binding = binding;}@NonNullpublic VB getBinding() {return binding;}}
}//使用方式
public class FooViewDelegate extends BindingViewDelegate<Foo, ItemFooBinding> {@Overrideprotected ItemFooBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {return ItemFooBinding.inflate(inflater, parent, false);}@Overridepublic void onBindViewHolder(@NotNull BindingViewHolder<ItemFooBinding> holder, Foo foo) {holder.getBinding().tvFoo.setText(item.getValue());}
}
反射

Activity

public abstract class BaseBindingActivity<VB extends ViewBinding> extends AppCompatActivity {private VB binding;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ViewBindingUtil.inflateWithGeneric(this, getLayoutInflater());setContentView(binding.getRoot());}public VB getBinding() {return binding;}
}//使用方式
public class MainActivity extends BaseBindingActivity<ActivityMainBinding>{@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);getBinding().getTvHelloWord().setText("Hello Android!");}
}

Fragment

public abstract class BaseBindingFragment<VB extends ViewBinding> extends Fragment {private VB binding;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = ViewBindingUtil.inflateWithGeneric(this, getLayoutInflater(), container, false);return binding.getRoot();}@Overridepublic void onDestroyView() {super.onDestroyView();binding = null;}public VB getBinding() {return binding;}
}//使用方式
class HomeFragment extends BaseBindingFragment<FragmentHomeBinding> {@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);getBinding().tvHelloWorld.setText("Hello Android!");}
}

Adapter

public abstract class BaseBindingQuickAdapter<T, VB extends ViewBinding>extends BaseQuickAdapter<T, BaseBindingQuickAdapter.BaseBindingHolder> {public BaseBindingQuickAdapter() {this(-1);}public BaseBindingQuickAdapter(@LayoutRes int layoutResId) {super(layoutResId);}@NotNull@Overrideprotected BaseBindingHolder onCreateDefViewHolder(@NotNull ViewGroup parent, int viewType) {VB viewBinding = ViewBindingUtil.inflateWithGeneric(this, parent);return new BaseBindingHolder(viewBinding);}public static class BaseBindingHolder extends BaseViewHolder {private final ViewBinding binding;public BaseBindingHolder(@NotNull View view) {this(() -> view);}public BaseBindingHolder(@NotNull ViewBinding binding) {super(binding.getRoot());this.binding = binding;}@NonNull@SuppressWarnings("unchecked")public <VB extends ViewBinding> VB getViewBinding() {return (VB) binding;}}
}//使用方式
class FooAdapter extends BaseBindingQuickAdapter<Foo, ItemFooBinding> {@Overridepublic void convert(@NotNull BindingViewHolder<ItemFooBinding> holder, Foo item) {ItemFooBinding binding = holder.getViewBinding();binding.tvFoo.setText(item.getValue());}
}

MultiType

public abstract class BindingViewDelegate<T, VB extends ViewBinding> extendsItemViewDelegate<T, BindingViewDelegate.BindingViewHolder<VB>> {@NotNull@Overridepublic BindingViewHolder<VB> onCreateViewHolder(@NotNull Context context, @NotNull ViewGroup parent) {return new BindingViewHolder<>(ViewBindingUtil.inflateWithGeneric(this, parent));}public static class BindingViewHolder<VB extends ViewBinding> extends RecyclerView.ViewHolder {private final VB binding;public BindingViewHolder(@NonNull VB binding) {super(binding.getRoot());this.binding = binding;}@NonNullpublic VB getBinding() {return binding;}}
}//使用方式
class FooViewDelegate extends BindingViewDelegate<Foo, ItemFooBinding> {@Overridepublic void onBindViewHolder(@NotNull BindingViewHolder<ItemFooBinding> holder, Foo item) {holder.getBinding().tvFoo.setText(item.getValue());}
}

组件化之路 - ViewBinding基类封装相关推荐

  1. android国籍组件,android组件化之路

    问题:实际业务变化快,而工程内各个功能模块耦合度太高,不能对功能模块进行快速方便地拆分或组装.团队共同开发中,可能一个文件同时被多人修改,导致每次更新提交代码都需要消耗大量时间去merge代码.每次修 ...

  2. 蘑菇街App的组件化之路·续

    原文:http://limboy.me/ios/2016/03/14/mgj-components-continued.html 蘑菇街 App 的组件化之路·续 前几天在「移动学习分享群」分享了关于 ...

  3. 组件化之路 - ViewModel一知半解

    新的一年,优先把欠账补齐,关于Jetpack下Lifecycle.ViewModel.LiveData组件库,以及ViewModel+LiveData项目实践,如今也只差ViewModel还没有记录了 ...

  4. android 蘑菇街组件化,蘑菇街 App 的组件化之路

    编辑推荐: 本文来自于csdn,文章主要分享了casatwy 的一些思路和思考问题的角度,希望对您的学习有帮助. 统一的调用实现 将「URL 调用」和「组件间调用」通过 runtime 达到统一,通过 ...

  5. android组件化蘑菇街,蘑菇街 App 的组件化之路·续

    前几天在「移动学习分享群」分享了关于蘑菇街组件化方面的一点经验,由于时间和文字描述方面的限制,很多东西表述的不是很清楚,让一些同学产生了疑惑,casatwy老师也写了篇文章来纠正其中的一些实现,看完之 ...

  6. android mvp框架基类,Android MVP架构项目搭建封装,基类封装

    综述 对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的.而对于Android应用的开发中本身可视为一种MVC架构 ...

  7. 百度App组件化之路

    原创:GuoJin 百度APP技术团队-资深技术专家 文章来源:百度APP技术微信公众号           组件化是一个老生常谈的涉及面很广的话题,即不是做好一件事而是做好一系列的事情才能达成:其中 ...

  8. 【超强干货】蘑菇街App的组件化之路

    本文为『移动前线』群在3月10日的分享总结整理而成,转载请注明来自『移动开发前线』公众号. 嘉宾介绍 蘑菇街李忠(花名银时,网名 limboy),多年客户端开发经验,目前主要负责移动端基础架构设计及核 ...

  9. 蘑菇街 App 的组件化之路

    在组件化之前,蘑菇街 App 的代码都是在一个工程里开发的,在人比较少,业务发展不是很快的时候,这样是比较合适的,能一定程度地保证开发效率. 慢慢地代码量多了起来,开发人员也多了起来,业务发展也快了起 ...

  10. 【Unity】UI交互组件之按钮Button可选基类总结

    按钮(Button) 按钮控件可以响应于用户的点击并触发启动或确认操作,比如Web表单上的Submit及Cancel按钮.主要有三大属性:Interactable / Transition / Nav ...

最新文章

  1. linux系统下添加新硬盘的方法详解
  2. Ubuntu 16.04修改显示字体大小(包括GNOME/Unity)
  3. c++17(17)-异常try catch,operator[],vector at
  4. 【亚伦博客】反方观点: 下载不是偷窃
  5. PAT甲级1051 栈的模拟
  6. 未格式化的硬盘识别失败
  7. mysql基本常用命令_mysql 的基本操作以及常用命令
  8. 机器学习十大算法简介
  9. 数据结构-顺序表基本操作的实现(含全部代码)
  10. 安装算量软件图纸复制操作
  11. cad怎么画立体图形教学_cad怎么绘制三维图形,cad三维制图实例图文教程
  12. mac上面的文件分割与合并
  13. 激光雷达Velodyne16配置及录制rosbag
  14. python文件处理基础_第六篇:python基础之文件处理
  15. 一位期货人的总结:大道至简,悟者大成
  16. centos 虚拟机出问题 Oh no,something has gone wrong! 解决方法
  17. 乐教乐学各关的解(3-10)
  18. 在css中引用特殊字体
  19. 「PS-CC2019新版教程」画板工具-基础篇
  20. 我眼中的中国科研:一个中科院退学博士生的感想

热门文章

  1. lzg_ad:FBW控制台命令详解
  2. 10个典型的大数据案例
  3. 教程篇(7.0) 01. 介绍FortiClient和FortiClient EMS ❀ FortiClient EMS ❀ Fortinet 网络安全专家 NSE 5
  4. android模拟器 opengl,在Android模拟器上缺少OpenGL驱动程序
  5. DEVC++实现街头篮球(爷青回)(1.01版)
  6. Rhino6.25软件安装教程|兼容WIN10
  7. 标准盒子模型简单讲解
  8. 单月销量破万台,FITURE治好了健身镜的“水土不服”?
  9. 下载网络图片并上传微信公众平台素材库
  10. Java控制流程-for 天朝有一个乞丐姓洪,去天桥要钱 第一天要了1块钱 第二天要了2块钱 第三天要了4块钱 第四天要了8块钱 洪乞丐干10天,收入是多少?