「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
DataBinding 是 Google 在 Jetpack 中推出的一款数据绑定的支持库, 能够省去我们一直以来的 findViewById() 步骤,大量减少 Activity / Fragment 内的代码,数据能够单向或双向绑定到 layout 文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常。使其维护起来更加方便,架构更明确简介。
绑定
有两种:
第一是将数据绑定在 UI 元素上
第二是将 UI 上的数据绑定到对应的数据模型中
本文教大家如何利用DataBinding来实现暗黑模式的切换\
原理
是利用DataBinding绑定控件颜色来实现颜色切换
此方法支持所有控件,缺点是入侵性太强了 只适合新项目
启用 DataBinding
在 app module 的 build.gradle 中添加如下代码即可:
android {
...
dataBinding {
enabled = true
}
}
布局代码
在默认的布局文件的最外层嵌套layout标签\
把
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
移到layout标签中
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
...
</layout>
在layout里面加入data和variable标签
backgroundColorPrimary是变量名
类型是Integer
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="backgroundColorPrimary"
type="Integer" />
</data>
...
</layout>
在需要换肤的控件下加入
android:background="@{backgroundColorPrimary}"
例如
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@{backgroundColorPrimary}">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@{backgroundColorPrimary}"
app:layout_scrollFlags="scroll|enterAlways">
<com.google.android.material.appbar.CollapsingToolbarLayout/>
<com.google.android.material.appbar.AppBarLayout/>
逻辑代码
在BaseActivity和BaseFragment里面加个抽象函数,用来刷新界面
public abstract void refreshUi();
接着利用Eventbus之类的框架来实现发送者和接收者解耦在
BaseActivity的onCreate和
BaseFragment的onCreateView下设置刷新UI的被观察者
XEventBus.observe(this, EventName.REFRESH_SHIN, true, new Observer<String>() {
@Override
public void onChanged(@Nullable String data) {
refreshUi();
}
});
每个数据绑定布局文件都会生成一个绑定类,ViewDataBinding 的实例名是根据布局文件名来生成,将布局文件名改为首字母大写的驼峰命名法来命名并且去掉下划线(’_’)。控件的获取方式类似,但首字母小写。
例如布局文件名是fragment_home.xml就会生成FragmentHomeBinding.java\
在里面Activity/Fragment里面继承BaseActivity/BaseFragment
private FragmentHomeBinding mBinding;
peivate boolean isLight = true;
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false);
在用来刷新界面的抽象函数里面给backgroundColorPrimary赋值
@Override
protected void refreshUi() {
mBinding.setBackgroundColorPrimary(getBackgroundColorPrimary());
}
public int getBackgroundColorPrimary() {
if (isLight)) {
isLight = false;
return getResources().getColor(R.color.backgroundColorPrimary_night);
} else {
isLight = true;
return getResources().getColor(R.color.backgroundColorPrimary);
}
}
点击切换
mBinding.tvTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
XEventBus.post(EventName.REFRESH_SHIN, SkinColorName.SHIN_NIGHT);
}
});
如果不用EventBus的话
mBinding.tvTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBinding.setBackgroundColorPrimary(getBackgroundColorPrimary());
}
});
效果图