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()
在 ProductListFragment
的 onItemClicked()
中添加以下代码
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()
所以情况是,我有一个 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()
在 ProductListFragment
的 onItemClicked()
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()