既然已经对 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. Angular多个页面引入同一个组件报错The Component ‘MyComponentComponent‘ is declared by more than one NgModule怎么办?
  2. EditPlus集成Java编译和运行命令组建轻量级Java SE开发工具
  3. 什么是URL?协议头,路径和端口是什么意思?
  4. while保留五位小数c语言,C语言教程(共同学习)
  5. 渡神纪帧数测试软件,渡神纪芬尼斯崛起配置要求高吗 渡神纪配置要求详细介绍_游侠网...
  6. 95%PyTorch库都会中招的bug!特斯拉AI总监都没能幸免
  7. 程序的记事本--log4net
  8. Html5 音效播放器
  9. 利用xml+xsl给客户机添加超级管理帐户!
  10. Delphi 中的 Var buffer 开类型参数
  11. 异常处理——MysqlCan't connect to local MySQL server through socket '/v ar/lib/mysql/mysql.sock'
  12. Bigo 实时计算平台建设实践
  13. C++ 带默认参数值的函数
  14. leetcode 665. 非递减数列(贪心算法)
  15. springboot 事务_Spring Boot中的事务是如何实现的?懂吗?
  16. 自用_C/C++报错记录汇总
  17. linux 编译ffmpeg 支持x264, x265
  18. vs 2015查看动态库
  19. AsyncResult使用场景
  20. How to disable cursor positioning and text selection in an EditText? (Android)

热门文章

  1. android摄像头(camera)之buffer管理
  2. tibco rv java实例_java – 我不允许使用Tibco Rendezvous确认消息的任何原因?
  3. 成为技术传播者(二):Why and Why NOT
  4. 数字电子技术-逻辑门电路
  5. IEEE802.3-2015 CL78 节能以太网(EEE)要点翻译
  6. ASP.NET复习资料
  7. 最新 9个免费建站空间 网站均免备案
  8. 南京计算机徐宪忠,nakaga
  9. Skipped,remains conflicted
  10. 大厂Java八股文面试真题汇总,2022秋招必备,面试不慌