将如何动态向使用XML创建的视图添加元素与https://dev59.com/d1kS5IYBdhLWcg3wKzqq#40527407合并。
我发现了一个“更简单”的解决方案,这对于添加多个一致的视图非常有效,它使用 Viewbinding 和 ViewModel。
- 创建fragment_home.xml
- 在fragment_home.xml底部添加LinearLayout
- 创建您要填充的dynamic_view.xml
- 从ViewModel / Array或任何可用的数据源中获取元素
- 填充并添加元素
在这种情况下,我正在创建一个标题文本视图和一个RecyclerView [有适用于此的库,但是我发现通过这样做能够获得更多的控制权]。
步骤1,2
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.hometab.HomeFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/dynamic_linear_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_large"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/curated_recycler" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
第三步
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/dynamic_constraint"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="@dimen/margin_large"
app:layout_constraintStart_toStartOf="parent" />
<View
android:id="@+id/title_view"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/shop_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/diary"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/black"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/title_view"
app:layout_constraintStart_toStartOf="@id/guideline"
app:layout_constraintTop_toTopOf="@+id/title_view" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/shop_recycler"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/guideline"
app:layout_constraintTop_toBottomOf="@+id/title_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
步骤四、五
binding = FragmentHomeBinding.inflate(getLayoutInflater());
ShopViewModel shopViewModel = new ViewModelProvider(this).get(ShopViewModel.class);
shopViewModel.getAllShops(false).observe(getViewLifecycleOwner(), shopEntities -> {
List<ConstraintLayout> shopConstraints = new ArrayList<>();
for (ShopEntity shopEntity : shopEntities) {
DynamicViewBinding dynamicViewBinding = DynamicViewBinding.inflate(getLayoutInflater());
dynamicViewBinding.shopName.setText(shopEntity.getName());
dynamicViewBinding.shopRecycler.setLayoutManager(new ProductCardLayoutManager(getContext(), 1,
GridLayoutManager.HORIZONTAL, false, 80));
productViewModel.getAllProductsByShop(shopEntity.getShopId(), 10).observe(getViewLifecycleOwner(), productEntities ->
dynamicViewBinding.shopRecycler.setAdapter(new ProductAdapter(getActivity(), productEntities)));
shopConstraints.add(dynamicViewBinding.getRoot());
}
binding.dynamicLinearLayout.removeAllViews();
for (ConstraintLayout shopConstraint : shopConstraints) {
binding.dynamicLinearLayout.addView(shopConstraint);
}
});