栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

组件化之路 - ViewBinding基类封装

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

组件化之路 - 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  extends AppCompatActivity {
    private T mBinding;

    @Override
    protected 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding.textView.text = "冲刺把,卡布达~"
    }

    @Override
    public ViewBinding getViewBinding() {
        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
        return mBinding;
    }
}
Kotlin - baseActivity
//基类封装
abstract class baseActivity : AppCompatActivity() {
    private lateinit var _binding: T
    protected 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() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.textView.text = "这是MainActivity"
    }

    override fun getViewBinding() = ActivityMainBinding.inflate(layoutInflater)
}
Kotlin - baseFragment
//基类封装
abstract class baseFragment : Fragment() {
    private lateinit var _binding: T
    protected 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() {
    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 extends AppCompatActivity {
  protected T viewBinding;

  @Override
  protected 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 {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewBinding.button.setText("这是 MainActivity ViewBinding");
        viewBinding.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("MainView","点击按钮");
            }
        });
    }
}
Java - baseFragment
//基类封装
public class baseFragment extends Fragment {
    protected T viewBinding;

    @Nullable
    @Override
    public 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{
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        viewBinding.button.setText("这是 MainFragment ViewBinding");
        viewBinding.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("MainView","点击按钮");
            }
        });
    }
}
Kotlin - baseActivity
//基类封装
open class baseActivity : AppCompatActivity() {
    protected lateinit var binding: T
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val type = javaClass.genericSuperclass as ParameterizedType
        val aClass = type.actualTypeArguments[0] as Class<*>
        val method = aClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
        binding = method.invoke(null, layoutInflater) as T
        setContentView(binding.root)
    }
}

//使用方式
class MainActivity : baseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.textView.text = "这是MainActivity"
    }
}
Kotlin - baseFragment
//基类封装
open class baseFragment:Fragment(){
    lateinit var binding: T
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val type = javaClass.genericSuperclass as ParameterizedType
        val 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 T
        return binding.root
    }
}

//使用方式
class FirstFragment : baseFragment() {
    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 extends AppCompatActivity {

  private VB binding;

  @Override
  protected 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 {
  @Override
  protected ActivityMainBinding onCreateViewBinding(@NonNull LayoutInflater layoutInflater) {
    return ActivityMainBinding.inflate(layoutInflater);
  }
    
  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getBinding().getTvHelloWord().setText("Hello Android!");
  }
}

Fragment

public abstract class baseBindingFragment extends Fragment {

  private VB binding;

  @Nullable
  @Override
  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    binding = onCreateViewBinding(inflater, container);
    return binding.getRoot();
  }

  @Override
  public 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 {
  @Override
  protected FragmentHomeBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent) {
    return FragmentHomeBinding.inflate(inflater, parent, false);
  }

  @Override
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getBinding().getTvHelloWord().setText("Hello Android!");
  }
}

Adapter

public abstract class baseBindingQuickAdapter
    extends baseQuickAdapter {

  public baseBindingQuickAdapter() {
    this(-1);
  }

  public baseBindingQuickAdapter(@LayoutRes int layoutResId) {
    super(-layoutResId);
  }

  @NotNull
  @Override
  protected 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 getViewBinding() {
      return (VB) binding;
    }
  }
}

//使用方式
public class FooAdapter extends baseBindingQuickAdapter {
  @Override
  protected ItemFooBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
    return ItemFooBinding.inflate(inflater, parent, false);
  }

  @Override
  protected void convert(@NotNull baseBindingHolder holder, Foo item) {
    ItemFooBinding binding = holder.getViewBinding();
    binding.tvFoo.setText(item.getValue());
  }
}

MultiType

public abstract class BindingViewDelegate extends
    ItemViewDelegate> {
  @NotNull
  @Override
  public BindingViewHolder 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 extends RecyclerView.ViewHolder {

    private final VB binding;

    public BindingViewHolder(@NonNull VB binding) {
      super(binding.getRoot());
      this.binding = binding;
    }

    @NonNull
    public VB getBinding() {
      return binding;
    }
  }
}

//使用方式
public class FooViewDelegate extends BindingViewDelegate {
  @Override
  protected ItemFooBinding onCreateViewBinding(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
    return ItemFooBinding.inflate(inflater, parent, false);
  }

  @Override
  public void onBindViewHolder(@NotNull BindingViewHolder holder, Foo foo) {
    holder.getBinding().tvFoo.setText(item.getValue());
  }
}
反射

Activity

public abstract class baseBindingActivity extends AppCompatActivity {

  private VB binding;

  @Override
  protected 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{

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getBinding().getTvHelloWord().setText("Hello Android!");
  }
}

Fragment

public abstract class baseBindingFragment extends Fragment {

  private VB binding;

  @Nullable
  @Override
  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    binding = ViewBindingUtil.inflateWithGeneric(this, getLayoutInflater(), container, false);
    return binding.getRoot();
  }

  @Override
  public void onDestroyView() {
    super.onDestroyView();
    binding = null;
  }

  public VB getBinding() {
    return binding;
  }
}

//使用方式
class HomeFragment extends baseBindingFragment {

  @Override
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getBinding().tvHelloWorld.setText("Hello Android!");
  }
}

Adapter

public abstract class baseBindingQuickAdapter
    extends baseQuickAdapter {

  public baseBindingQuickAdapter() {
    this(-1);
  }

  public baseBindingQuickAdapter(@LayoutRes int layoutResId) {
    super(layoutResId);
  }

  @NotNull
  @Override
  protected 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 getViewBinding() {
      return (VB) binding;
    }
  }
}

//使用方式
class FooAdapter extends baseBindingQuickAdapter {

  @Override
  public void convert(@NotNull BindingViewHolder holder, Foo item) {
    ItemFooBinding binding = holder.getViewBinding();
    binding.tvFoo.setText(item.getValue());
  }
}

MultiType

public abstract class BindingViewDelegate extends
    ItemViewDelegate> {
  @NotNull
  @Override
  public BindingViewHolder onCreateViewHolder(@NotNull Context context, @NotNull ViewGroup parent) {
    return new BindingViewHolder<>(ViewBindingUtil.inflateWithGeneric(this, parent));
  }

  public static class BindingViewHolder extends RecyclerView.ViewHolder {

    private final VB binding;

    public BindingViewHolder(@NonNull VB binding) {
      super(binding.getRoot());
      this.binding = binding;
    }

    @NonNull
    public VB getBinding() {
      return binding;
    }
  }
}

//使用方式
class FooViewDelegate extends BindingViewDelegate {

  @Override
  public void onBindViewHolder(@NotNull BindingViewHolder holder, Foo item) {
    holder.getBinding().tvFoo.setText(item.getValue());
  }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/462203.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号