组件化之路 - ViewBinding基类封装
既然已經(jīng)對 ViewBinding一知半解 ,那么接下來肯定是要集成到項目中跑起來,所以此篇主講關(guān)于ViewBinding集成在基類的具體方式~
兄弟篇
- 組件化之路 - ViewBinding一知半解
- 組件化之路 - ViewBinding基類封裝
我看了看網(wǎng)上關(guān)于ViewBinding基類集成,一般都是通過反射、非反射的方法去集成基類,進行使用的 > <
我自己稍作總結(jié)后,得出以下結(jié)論,通篇也以此結(jié)論進行說明
關(guān)于ViewBinding基類集成,主要集成有倆種方式
- 常規(guī)寫法,手動通過原始代碼封裝Base基類,達到基類封裝效果,從而運用到自己的項目
- 三方框架,如加入 ViewBindingKTX 框架,包體積雖有增大,但作者能解決一些自己后續(xù)會遇到或忽略的問題 (起初是我朋友推薦,后來在知乎看到了原作者也在推薦)
關(guān)于ViewBinding基類集成,主要集成有倆種用法
- 非反射(不使用反射,常規(guī)寫法)
- 反射(如果代碼混淆的話,容易出現(xiàn)找不到類的場景)
關(guān)于ViewBinding基類集成,主要集成有倆種開發(fā)語言
- Java
- Kotlin
因為我用Kotlin經(jīng)驗還不足,所以我自己寫了一下Java - BaseActivity基類封裝 ~
- 常規(guī)集成(不使用反射)
- Java - BaseActivity
- Kotlin - BaseActivity
- Kotlin - BaseFragment
- 反射集成
- Java - BaseActivity
- Java - BaseFragment
- Kotlin - BaseActivity
- Kotlin - BaseFragment
- 三方框架
- Feature
- 基礎(chǔ)配置
- Java改造基類
- 不使用反射
- 反射
常規(guī)集成(不使用反射)
關(guān)于ViewBinding基類封裝的很多知識,借鑒了此篇 blog 的尾部代碼(當然,這類型代碼太常見了,至少我看到多篇相似的封裝方式,不過一點兒都不影響我的學習熱情,加油 ) ~
Java - BaseActivity
這種方式,也是我在項目中使用的方式,經(jīng)本人親自嘗試,可用 ~ 但要注意ViewBinding在不同場景的使用方式有所不同,此處僅作用于Activity相關(guān)組件, 如不懂可前往ViewBinding繼續(xù)進階 ~
//基類封裝 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的原作者,實屬無聊,權(quán)當記錄把...
Feature
- 支持 Kotlin 和 Java 用法
- 支持多種使用反射和不使用反射的用法
- 支持封裝改造自己的基類,使其用上 ViewBinding
- 支持 BaseRecyclerViewAdapterHelper
- 支持 Activity、Fragment、Dialog、Adapter
- 支持在 Fragment 自動釋放綁定類的實例對象
- 支持實現(xiàn)自定義組合控件
- 支持 TabLayout 實現(xiàn)自定義標簽布局
- 支持 NavigationView 設(shè)置頭部控件
- 支持 DataBinding 自動設(shè)置 lifecycleOwner
基礎(chǔ)配置
build(project)
allprojects {repositories {...maven { url 'https://www.jitpack.io' }} }build(app)
android {buildFeatures {viewBinding = true} }dependencies {// 以下都是可選,請根據(jù)需要進行添加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改造基類
因?qū)τ贙otlin還不熟,所以僅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());} }總結(jié)
以上是生活随笔為你收集整理的组件化之路 - ViewBinding基类封装的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hulu简介
- 下一篇: String 与 char* 相互转换