最近项目想换成MVVMHabit框架,然而这才刚用,我就发现了一个问题,文档关于ViewPager这一块的内容几乎没有,没办法,只好自己去研究了,顺便写个demo让自己和其他人学习学习。我先创建了必备的GuidanceActivity、GuidanceViewModel、GuidanceItemViewModel,还有两个布局文件,代码很简单,这里就不赘述了,直接贴代码:
public class GuidanceActivity extends BaseActivity<ActivityGuidanceBinding, GuidanceViewModel> {
@Override
public int initContentView(Bundle savedInstanceState) {
return R.layout.activity_guidance;
}
@Override
public int initVariableId() {
return BR.viewModel;
}
@Override
public GuidanceViewModel initViewModel() {
return new GuidanceViewModel(this);
}
@Override
public void initViewObservable() {
super.initViewObservable();
}
}
activity的布局文件代码如下:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:binding="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.goldze.mvvmhabit.ui.vm.GuidanceViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/vp_guidance"
android:layout_width="match_parent"
android:layout_height="match_parent"
binding:onPageSelectedCommand="@{viewModel.pageSelectedCommand}"
binding:itemBinding="@{viewModel.itemBinding}"
binding:items="@{viewModel.observableList}" />
<Button
android:id="@+id/btn_access_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:background="@color/colorPrimary"
android:text="@string/access_now"
android:textColor="@color/white"
android:visibility="@{viewModel.accessVisibility}"
binding:onClickCommand="@{viewModel.accessOnClickCommand}" />
</RelativeLayout>
</layout>
在布局代码里面,我们可以看到ViewPager有下面三行代码:
binding:onPageSelectedCommand="@{viewModel.pageSelectedCommand}"
binding:itemBinding="@{viewModel.itemBinding}"
binding:items="@{viewModel.observableList}"
其实它们就对应着我要在GuidanceViewModel中要定义的变量了,items很明显就相当于我们所有Item的数据List,而itemBinding就是我们要去设置子Item布局等参数的变量了。
//给ViewPager添加items
public ObservableList<GuidanceItemViewModel> observableList = new ObservableArrayList<>();
//给ViewPager添加ItemBinding
public ItemBinding<GuidanceItemViewModel> itemBinding = ItemBinding.of(BR.viewModel, R.layout.item_guidance);
// 引导页
public int[] mGuidanceIdList = new int[]{R.drawable.guidance1, R.drawable.guidance2, R.drawable.guidance3, R.drawable.guidance4};
public ObservableInt accessVisibility = new ObservableInt(View.INVISIBLE);
public GuidanceViewModel(Context context) {
super(context);
for (int i = 0; i < mGuidanceIdList.length; i++) {
observableList.add(new GuidanceItemViewModel(context, mGuidanceIdList[i]));
}
}
public BindingCommand pageSelectedCommand = new BindingCommand<>(new BindingConsumer<Integer>() {
@Override
public void call(Integer integer) {
if (integer == observableList.size() - 1) {
accessVisibility.set(View.VISIBLE);
}
}
});
上面代码中的observableList就对应布局中的 binding:items="@{viewModel.observableList}",同理itemBinding,另外为了监听页面的切换,这里写了一个pageSelectedCommand方法,而call方法里面的integer就对应了当前页面所在的位置。另外为了能测试,我这里虚构了四条数据,子Item的布局也很简单,就一个ImageView对应资源文件中固定的图片路径,当然为了让后台可以控制引导页图片的显示,所以mGuidanceIdList中的图片我们就把它传给GuidanceItemViewModel中的imageId,具体看对应的代码:
public class GuidanceItemViewModel extends BaseViewModel {
public String imgUrl = "";
public int imgId;
public GuidanceItemViewModel(Context context, int drawableId) {
this.context = context;
imgId = drawableId;
}
}
<layout>
<data>
<import type="com.goldze.mvvmhabit.R" />
<variable
name="viewModel"
type="com.goldze.mvvmhabit.ui.vm.GuidanceItemViewModel" />
</data>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:binding="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
binding:placeholderRes="@{viewModel.imgId}"
binding:url="@{viewModel.imgUrl}" />
</RelativeLayout>
</layout>
因为我这边imgUrl没有设置值,考虑到因网络原因拿不到引导页的网络图片链接,然而测试的时候就发现我的默认图片也没有显示出来,这是为什么呢?查看了一下源码发现这样一段:
if (!TextUtils.isEmpty(url)) {
//使用Glide框架加载图片
Glide.with(imageView.getContext())
.load(url)
.apply(new RequestOptions().placeholder(placeholderRes))
.into(imageView);
}
想要改成判断是否为null即可,结果却发现还是会有问题,于是给ImageView设置一个src,可以直接在布局xml文件中写死,如果希望默认图片有多种的话,就可以写成"android:src="@{viewModel.drawable}",再根据不同情况去viewModel里面用代码控制即可。就这样,对于如何使用MVVMHabit中的ViewPager的理解告一段落了。