Android 使用数据绑定库动态包含布局
Android include layout dynamically with data-binding library
我将 MVVM 框架用于 Android 带有数据绑定库的应用程序。
我有一些可重复使用的组件,每个 activity 都应该有。 f.e。工具栏、菜单、浮动操作按钮。
我想创建一个通用 activity,它将实现所有这些可重用的功能,然后每个 activity class 都将从这个通用 activity 继承。我也有 GenericViewModel class 并且所有其他 ViewModel 都是从这个通用 class.
继承的
但是我的布局有问题。我想创建通用布局文件并动态地包含子布局。 f.e.
<?xml version="1.0" encoding="utf-8"?>
<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="data"
type="com.mypackage.genericViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
bind:data="@{data}"
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="@{Here i want to have dynamic variable}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout></layout>
我不想为每个 activity 复制/粘贴此代码,但数据绑定库不允许动态包含布局。这种情况有什么解决办法吗?
这是我的解决方案,希望对你有帮助,我觉得不是很好way.If你找到更好的方法,请告诉我。谢谢!
虽然数据绑定库不允许动态包含布局,但我们可以为不同的布局使用不同的 ViewModel。我使用 LinearLayout 作为容器来承载动态布局,然后覆盖 Activity setContentView 方法来添加查看我的容器(LinearLayout)。
通用Activity
protected GenericViewBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.generic_view);
}
@Override
public void setContentView(View view) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mBinding.container.addView(view,lp);
}
generic_view布局
<data>
<variable
name="genericViewModel"
type=".viewModel.GenericViewModel"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<!--a custom view,some generic layout -->
<.view.base.BaseTitleView
android:id="@+id/base_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/base_title"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
具体Activity你可以这样使用它:
混凝土Activity
//different layout use different ViewModel here,generic logic&layout is in GenericActivity&generic_view layout.
private ActivityConcreteBinding mActivityConcreteBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityConcreteBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.activity_concrete,null,false);
setContentView(mActivityConcreteBinding.getRoot());
ConcreteViewModel concreteViewModel = new ConcreteViewModel(mBinding);//mBinding from GenericActivity, deliver it into ConcreteViewModel to do some generic logic.
...
}
对我来说,不再需要为每个 activity 复制粘贴通用布局。
我将 MVVM 框架用于 Android 带有数据绑定库的应用程序。
我有一些可重复使用的组件,每个 activity 都应该有。 f.e。工具栏、菜单、浮动操作按钮。
我想创建一个通用 activity,它将实现所有这些可重用的功能,然后每个 activity class 都将从这个通用 activity 继承。我也有 GenericViewModel class 并且所有其他 ViewModel 都是从这个通用 class.
继承的但是我的布局有问题。我想创建通用布局文件并动态地包含子布局。 f.e.
<?xml version="1.0" encoding="utf-8"?>
<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="data"
type="com.mypackage.genericViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
bind:data="@{data}"
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="@{Here i want to have dynamic variable}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout></layout>
我不想为每个 activity 复制/粘贴此代码,但数据绑定库不允许动态包含布局。这种情况有什么解决办法吗?
这是我的解决方案,希望对你有帮助,我觉得不是很好way.If你找到更好的方法,请告诉我。谢谢!
虽然数据绑定库不允许动态包含布局,但我们可以为不同的布局使用不同的 ViewModel。我使用 LinearLayout 作为容器来承载动态布局,然后覆盖 Activity setContentView 方法来添加查看我的容器(LinearLayout)。
通用Activity
protected GenericViewBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.generic_view);
}
@Override
public void setContentView(View view) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mBinding.container.addView(view,lp);
}
generic_view布局
<data>
<variable
name="genericViewModel"
type=".viewModel.GenericViewModel"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<!--a custom view,some generic layout -->
<.view.base.BaseTitleView
android:id="@+id/base_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/base_title"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
具体Activity你可以这样使用它:
混凝土Activity
//different layout use different ViewModel here,generic logic&layout is in GenericActivity&generic_view layout.
private ActivityConcreteBinding mActivityConcreteBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityConcreteBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.activity_concrete,null,false);
setContentView(mActivityConcreteBinding.getRoot());
ConcreteViewModel concreteViewModel = new ConcreteViewModel(mBinding);//mBinding from GenericActivity, deliver it into ConcreteViewModel to do some generic logic.
...
}
对我来说,不再需要为每个 activity 复制粘贴通用布局。