您的代码与您的 XML 不一致,所以这可能是一个问题。但是您可能会遇到我们在 TabLayouts 和数据绑定方面遇到的问题。
根本原因似乎是 TabLayout 在 XML 中使用了TabItem,但它在运行时将其转换为Tab。这搞砸了用于创建其引用的内部映射数据绑定。在我们的例子中,我们的 TabItem 实例是从错误的对象中转换而来的。在您的情况下,听起来它可能只是一个空对象。
在任何一种情况下,您似乎都不能可靠地将TabLayout 与数据绑定一起使用。我们最终创建了一个自定义 View,它只包装了一个 TabLayout,然后通过直接访问它的 Tab 项目手动“绑定”数据。
例如,带有TabLayout的布局:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="viewModel" type="com.app.ViewModel" />
</data>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/white"
app:onTabSelectedListener="@{viewModel.onTabSelectedListener}">
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/custom_tab_layout">
</android.support.design.widget.TabItem>
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/custom_tab_layout">
</android.support.design.widget.TabItem>
</android.support.design.widget.TabLayout>
然后是包装它的自定义视图:
public class CustomTabLayout extends FrameLayout {
private CustomTabLayoutBinding mBinding;
public CustomTabLayout(@NonNull Context context) {
this(context, null);
}
public CustomTabLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTabLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater inflater = LayoutInflater.from(context);
View tabLayout = inflater.inflate(R.layout.custom_tab_layout, this, false);
addView(tabLayout);
if (!isInEditMode()) {
mBinding = CustomTabLayoutBinding.bind(tabLayout);
}
}
public void setViewModel(@Nullable ViewModel viewModel) {
mBinding.setViewModel(viewModel);
if (viewModel != null) {
updateTabAtIndex(viewModel.getFirstTabViewModel(), 0, viewModel.getSelectedIndex());
updateTabAtIndex(viewModel.getSecondTabViewModel(), 1, viewModel.getSelectedIndex());
}
}
private void updateTabAtIndex(TabViewModel tabViewModel, int index, int selectedIndex) {
TabLayout.Tab tab = mBinding.tabLayout.getTabAt(index);
if (tab == null) {
return;
}
View customView = tab.getCustomView();
if (customView == null) {
return;
}
if (index == selectedIndex) {
tab.select();
}
TextView textView = (TextView) customView.findViewById(R.id.title);
textView.setText(tabViewModel.getTitleText());
TextView subTitleTV = (TextView) customView.findViewById(R.id.subtitle);
subTitleTV.setText(tabViewModel.getSubTitleText());
}
}
然后在需要 TabLayout 的布局中,改用自定义视图:
<com.app.CustomTabLayout
android:id="@+id/custom_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="@dimen/default_toolbar_elevation"
app:viewModel="@{viewModel.getTabsViewModel}" />
我们在这里使用 MVVM,但希望您明白要点:通过提供公共 setViewModel(或 setMyData 或其他)方法,您仍然可以在使用自定义选项卡布局的地方利用数据绑定,但随后可以控制手动设置TabLayout 中Tab 对象的属性。
希望有帮助!