Kotlin 从 JSON 改造响应中提取信息并将它们映射到 Textview

Kotlin extract information from JSON retrofit response and map them to Textview

所以情况是,我有一个 recyclerview ProductListFragment.kt,每个项目都有点击侦听器,它将显示一个弹出对话框 up.Something,如 this. The dialog that contained the information of each item will be shown in the popup dialog like this。

这是 ProductListFragment.kt recyclerview 的适配器:

ProductListAdapter.kt

class ProductListItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    private val productName: TextView = itemView.productName
    private val productPrice: TextView = itemView.productPrice
    private val productStockQuantity: TextView = itemView.productStockQuantity

    private val detailProductName: TextView = itemView.findViewById(R.id.detailProductName)
    private val detailProductPrice: TextView = itemView.findViewById(R.id.detailProductPrice)
    private val detailProductLastUpdate: TextView = itemView.findViewById(R.id.detailProductLastUpdate)
    private val detailProductStockQty: TextView = itemView.findViewById(R.id.detailProductStockQty)

    fun bind(
        product: ProductListPOJODataClassesDataItem,
        clickListener: ProductListOnItemClickListener
    ) {

        //This is for showing the information in each recyclerview item

        productName.text = product.proName
        productPrice.text = product.proSaleprice.toString()
        productStockQuantity.text = product.stkAllqty.toString()


        //And these are for the detail popup dialog content

        detailProductName.text = product.proName
        detailProductPrice.text = product.proSaleprice.toString()
        detailProductLastUpdate.text = product.sktLastupdate
        detailProductStockQty.text = product.stkAllqty.toString()

        itemView.setOnClickListener {
            clickListener.onItemClicked(product)
        }
    }
}


class ProductListAdapter(
    private var productList: ProductListPOJODataClasses,
    private val itemClickListener: ProductListOnItemClickListener
) : RecyclerView.Adapter<ProductListItemHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductListItemHolder {
        val v = LayoutInflater.from(parent.context)
            .inflate(R.layout.product_list_item_layout, parent, false)

        return ProductListItemHolder(v)
    }

    override fun getItemCount(): Int {
        return productList.data!!.size
    }

    override fun onBindViewHolder(holder: ProductListItemHolder, position: Int) {
        val product = productList.data?.get(position)
        if (product != null) {
            holder.bind(product, itemClickListener)
        }
    }
}


interface ProductListOnItemClickListener {
    fun onItemClicked(product: ProductListPOJODataClassesDataItem)
}

从上面的代码可以看出,recyclerview 项目和详细信息对话框访问相同的 JSON 数据 class。

这是ProductListFragment.kt本身的代码片段

ProductListFragment.kt

   override fun onItemClicked(product: ProductListPOJODataClassesDataItem) {
         //Inflate the dialog with custom view
        val mDialogView = LayoutInflater.from((activity as AppCompatActivity)).inflate(
            R.layout.product_list_dialog_layout, null
        )

        val selectedStkOutcode = product.stkOutcode
        val selectedProcode = product.stkProdcode

        if (selectedStkOutcode != null && selectedProcode != null) {

            // These line below show the information i desired in the log.

            Log.i("Product", "Clicked product name: ${product.proName}")
            Log.i("Product", "Clicked product price: ${product.proSaleprice}")
            Log.i("Product", "Clicked product stock qty: ${product.stkAllqty}")
            Log.i("Product", "Clicked product last update: ${product.sktLastupdate}")
        }

        //AlertDialogBuilder
        val mBuilder = AlertDialog.Builder((activity as AppCompatActivity))
            .setView(mDialogView)
            .setTitle("Product X")
        //show dialog
        val mAlertDialog = mBuilder.show()

        mDialogView.closeButton.setOnClickListener {
            //dismiss dialog
            mAlertDialog.dismiss()
        }
    }

如您所见,我提到它在 LogCat 中显示了我想要的相同信息。我想做同样的事情,但在对话框弹出窗口中。 我认为通过使用一个适配器,recyclerview 和详细信息的弹出对话框就足够了。

这是改造后的响应(我上面提到的 LogCat 显示了同样的事情):

我想在弹出的对话框中显示所有六个变量,但问题是它 returns

itemView.findViewById(R.id.detailProductName) must not be null

我知道这会发生,因为 detailProductName 未包含在回收站视图中。它是弹出对话框中的文本视图。

如何在对话框弹出窗口中显示所有信息?如果有任何我想念的细节或您想知道的,请在评论中提及。

编辑: 这是详细对话框布局

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp">
            <TextView
                android:id="@+id/detailProductName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="X"
                android:textSize="12sp"
                android:layout_marginTop="10dp"/>
            <TextView
                android:id="@+id/detailProductPrice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Rp. XXXXX"
                android:layout_marginTop="10dp"
                android:textSize="12sp"/>
            <TextView
                android:id="@+id/detailProductStockQty"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="XX "
                android:layout_marginTop="10dp"
                android:textSize="12sp"/>
            <TextView
                android:id="@+id/detailProductLastUpdate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="XX - XX - XXXX"
                android:layout_marginTop="10dp"
                android:textSize="12sp"/>

        </LinearLayout>

这是product_list_item_layout.xml

<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/CardView"
    android:id="@+id/sampleProductCard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_rowWeight="1"
    android:layout_columnWeight="1"
    android:layout_margin="12dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="6dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingBottom="8dp"
        >

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:src="@drawable/ic_launcher_background"
            />


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_marginLeft="12dp"
            android:layout_marginRight="12dp"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:text="Apple Pie"
                android:textColor="#6f6f6f"
                android:textSize="14sp"
                android:id="@+id/productName"/>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="12dp"
                    android:text="Rp. "
                    android:textColor="#6f6f6f"
                    android:textSize="12sp" />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="12dp"
                    android:layout_marginLeft="2dp"
                    android:text="Price"
                    android:textColor="#6f6f6f"
                    android:textSize="12sp"
                    android:id="@+id/productPrice"/>

            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="4dp"
                    android:text="Stock :"
                    android:textColor="#000"
                    android:textSize="10sp"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="4dp"
                    android:layout_marginLeft="6dp"
                    android:text="4"
                    android:textColor="#000"
                    android:textSize="10sp"
                    android:id="@+id/productStockQuantity"
                    />
            </LinearLayout>

        </LinearLayout>



    </LinearLayout>
</com.google.android.material.card.MaterialCardView>

首先,您没有向我们展示 product_list_item_layout,我确定此布局不包含任何 detailProductName。但是您使用此布局在 RV 中显示数据。因此,我可以建议您:您可以在 RV 适配器内部显示对话,无需创建用于将数据从 RV 适配器发送到片段的接口。然后,警报对话框一般可用于显示基本信息。为此,我建议您像这样使用 Dialog

val dialog = Dialog(context!!)
dialog.setContentView(R.layout.product_list_dialog_layout)
dialog.findViewById<View>(R.id.detailProductName).text = "some text will be here"

Objects.requireNonNull<Window>(dialog.window).setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()

很好的教程here. On the other hand if you want to use AlertDialog you can use these tutorials: 1 and 2。因此,在适配器中,您可以执行从单击项目接收所有数据并在对话中表示的功能。祝你好运:)

代码的问题是将 dialog's view 绑定到 recyclerview's 布局的 view,它不存在,因此它返回 null。请按照以下说明尝试

ProductListItemHolder

中删除以下内容
    private val detailProductName: TextView = itemView.findViewById(R.id.detailProductName)
    private val detailProductPrice: TextView = itemView.findViewById(R.id.detailProductPrice)
    private val detailProductLastUpdate: TextView = itemView.findViewById(R.id.detailProductLastUpdate)
    private val detailProductStockQty: TextView = itemView.findViewById(R.id.detailProductStockQty)

    detailProductName.text = product.proName
    detailProductPrice.text = product.proSaleprice.toString()
    detailProductLastUpdate.text = product.sktLastupdate
    detailProductStockQty.text = product.stkAllqty.toString()

ProductListFragmentonItemClicked()

中添加以下代码
 val mDialogView = LayoutInflater.from((this as AppCompatActivity)).inflate(
                R.layout.product_list_dialog_layout, null
        )
 val detailProductName: TextView = mDialogView.findViewById(R.id.detailProductName)
 val detailProductPrice: TextView = mDialogView.findViewById(R.id.detailProductPrice)
 val detailProductLastUpdate: TextView = mDialogView.findViewById(R.id.detailProductLastUpdate)
 val detailProductStockQty: TextView = mDialogView.findViewById(R.id.detailProductStockQty)

detailProductName.text = product.proName
detailProductPrice.text = product.proSaleprice.toString()
detailProductLastUpdate.text = product.sktLastupdate
detailProductStockQty.text = product.stkAllqty.toString()