【发布时间】:2021-05-04 08:54:16
【问题描述】:
我已经设置了视图模型、实时数据、回收器视图、适配器和视图持有者来呈现以下 JSON 响应。有效负载还有其他属性,但与widthUnit 相比,它们并不那么重要。
{
"canvasUnit": 16,
"specials": [{
"display_name": "Noodle Dish with Roasted Black Bean Sauce",
"heightUnit": 8,
"widthUnit": 16
},
{
"display_name": "Onion Flavored Rings",
"heightUnit": 8,
"widthUnit": 8
},
{
"display_name": "Kikkoman Less Sodium Soy Sauce",
"heightUnit": 8,
"widthUnit": 8
},
{
"display_name": "Organic Romaine Hearts",
"heightUnit": 4,
"widthUnit": 14
},
{
"display_name": "Navel Oranges 4LBS",
"heightUnit": 6,
"widthUnit": 4
},
{
"display_name": "Doritos Ranch",
"heightUnit": 6,
"widthUnit": 4
},
{
"display_name": "Lindt Hello Cookies & Cream 1.4 oz",
"heightUnit": 6,
"widthUnit": 4
}
]
}
根据widthUnit 与canvasUnit 的比率,我需要在同一行上拥有可变数量的视图。在此示例中,第一行的比率为 16 / 16 = 1。所以第一行应该显示与第一行相关的条目
接下来的两个 JSON 对象的值为 widthUnit 为 8。因此它们与 maxUnit 的比率为 0.5,这意味着我需要在第二行显示接下来的两个项目。
同样,由于接下来的 4 个条目的累积宽度为 16,因此应在第 3 行显示 4 个条目。
所以最终的布局应该是这样的
---------------------------------
| |
| ----------------------------- |
| | | |
| | entry # 1 | |
| | | |
| ------------------------------ |
|
| ------------ ------------ |
| | entry # 2 | | entry # 3 | |
| ------------- ----------- |
| ---- ---- ---- ----- |
| | #4 | | #5 | | #6 | | #7 | |
| ---- --- ---- ----- |
---------------------------------
我该如何完成这样的事情?我试过像这样使用 FlexLayoutManager
在我的活动的onCreate 函数中,
我已经初始化了适配器,如下
val recyclerAdapter = RecyclerAdapter(this) // Passing the context to the adapter.
val recyclerView = findViewById(R.id.recycler_view)
with(recyclerView) {
val flexboxLayoutManager = FlexboxLayoutManager(this@MyActivity).apply {
flexDirection = FlexDirection.ROW
justifyContent = JustifyContent.FLEX_START
flexWrap = FlexWrap.WRAP
}
layoutManager = flexboxLayoutManager
adapter = recyclerAdapter
setHasFixedSize(true)
}
适配器代码
class RecyclerAdapter(
private val context: Context
): RecyclerView.Adapter<ViewHolder>() {
var item: Item? = null;
override fun getItemCount(): Int = item?.specials?.size ?: 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val itemBinding: ItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.item, parent, false)
return ViewHolder(context, itemBinding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindViewHolder(item?.specials?.get(position), item?.canvasUnit)
}
}
ViewHolder
class ViewHolder(
private val context: Context,
private val itemBinding: ItemBinding,
): RecyclerView.ViewHolder(
itemBinding.root
) {
fun bindViewHolder(special: Specials?, canvasUnit: Int?) {
special ?: return
canvasUnit ?: return
itemBinding.special = special
itemBinding.executePendingBindings()
}
}
布局
<?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>
<import type="android.view.View"/>
<variable
name="special"
type="com.myproject.mobile.model.Specials" />
</data>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/standardMargin2x"
android:padding="@dimen/standardMargin2x"
style="@style/CardView"
android:visibility="@{special != null ? View.VISIBLE : View.GONE}">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/standardMargin"
android:orientation="horizontal">
<ImageView
android:id="@+id/product_image_url"
android:layout_width="@dimen/product_image_width"
android:layout_height="@dimen/product_image_height"
android:importantForAccessibility="no"
android:layout_alignParentStart="true"
android:scaleType="fitCenter"
android:contentDescription="@null"
android:layout_marginEnd="@dimen/standardMargin2x"
app:imageUrl="@{special.imageUrl}" />
<LinearLayout
android:id="@+id/product_price_container"
android:layout_marginStart="@dimen/standardMargin2x"
android:layout_marginBottom="@dimen/standardMargin2x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/product_image_url"
android:layout_alignParentEnd="true"
android:layout_alignWithParentIfMissing="true"
android:orientation="vertical"
android:layout_marginEnd="@dimen/standardMargin2x"
android:gravity="end">
<TextView
android:id="@+id/product_original_price"
android:layout_marginBottom="@dimen/standardMargin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/strikethrough"
android:textAppearance="@style/TextAppearance"
app:inUSD="@{special.originalPrice}"
tools:text="$5.00"/>
<TextView
android:id="@+id/product_price"
android:layout_marginBottom="@dimen/standardMargin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Secondary"
app:inUSD="@{special.price}"
tools:text="$5.00"/>
</LinearLayout>
<TextView
android:id="@+id/product_display_name"
android:layout_width="@dimen/text_display_width"
android:layout_height="wrap_content"
android:gravity="center|center_vertical"
android:layout_centerHorizontal="true"
android:layout_below="@id/product_price_container"
android:maxLines="2"
android:ellipsize="end"
android:text="@{special.displayName}"
android:textAppearance="@style/TextAppearance.Bold"
tools:text="Onion flavoured rings"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</layout>
数据在卡片视图中呈现如下
但我希望根据我的要求呈现条目。我怎样才能实现这样的事情?我试过浏览以下帖子
【问题讨论】:
标签: android android-recyclerview