[英]Pass data from recyclerView to new activity when an item is clicked Kotlin
[英]Android Kotlin get data from a clicked item in Recyclerview and pass it between fragments
所以我有兩個數據類( OutletListDataClass
和ProductListDataClass
),當前由兩個不同的片段( OutletListFragment.kt
和ProductListFragment.kt
,直接連接在導航圖中)使用。
這兩個片段都是 RecyclerView。 我想從OutletListFragment.kt
(包含在兩個數據類中)中的單擊項目中提取信息並將其傳遞給ProductListFragment.kt
。
這些是我在兩個片段中使用的數據類:
OutletListDataClass
data class OutletListPOJODataClasses(
@SerializedName("data")
@Expose
var data: List<OutletListPOJODataClassesDataItem>? = null,
@SerializedName("error")
val error: OutletListDataClassError? = null
)
data class OutletListPOJODataClassesDataItem(
@SerializedName("stk_prodcode")//Both data classes have this variable
@Expose
val stkProdcode: String? = null,
@SerializedName("stk_allqty")
@Expose
val stkAllqty: Int? = null,
@SerializedName("skt_lastupdate")
@Expose
val sktLastupdate: String? = null,
@SerializedName("outlet_address")
@Expose
val outletAddress: String? = null,
@SerializedName("outlet_name")
@Expose
val outletName: String? = null,
@SerializedName("stk_outcode")
@Expose
val stkOutcode: String? = null
)
產品列表數據類
data class ProductListPOJODataClasses(
@field:SerializedName("data")
val data: List<ProductListPOJODataClassesDataItem?>? = null,
@field:SerializedName("error")
val error: ProductListDataClassError? = null
)
data class ProductListDataClassError(
@field:SerializedName("msg")
val msg: String? = null,
@field:SerializedName("code")
val code: Int? = null,
@field:SerializedName("status")
val status: Boolean? = null
)
data class ProductListPOJODataClassesDataItem(
@field:SerializedName("stk_prodcode") //Both data classes have this variable
val stkProdcode: String? = null,
@field:SerializedName("stk_allqty")
val stkAllqty: Int? = null,
@field:SerializedName("pro_saleprice")
val proSaleprice: Int? = null,
@field:SerializedName("skt_lastupdate")
val sktLastupdate: String? = null,
@field:SerializedName("stk_outcode")
val stkOutcode: String? = null,
@field:SerializedName("pro_name")
val proName: String? = null
)
如您所見,這兩個數據類包含 sa.me 變量(StkOutcode)。 這就是我想要提取的(來自OutletListDataItem
)
這是當前OutletListFragment.kt
的代碼片段:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
(activity as AppCompatActivity).supportActionBar?.title = "Product List"
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_product_stock_outlet_list,
container,
false
)
//Show Progressbar While loading data
showProgressBar()
//Apply layout manager
binding.rvOutletList.layoutManager = LinearLayoutManager((activity as AppCompatActivity))
//Fetch Outlet List Data
fetchOutletListData()
// Declare that this fragment has menu
setHasOptionsMenu(true)
// Set action bar title to "Outlet List"
(activity as AppCompatActivity).supportActionBar?.title = "Outlet List"
return binding.root
}
這是我為 OutletListFragment 創建的 recyclerview 適配器。 插座列表適配器
class OutletListItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(
outlet: OutletListPOJODataClassesDataItem,
clickListener: OutletListOnItemClickListener?
) {
itemView.outletName.text = outlet.outletName
itemView.setOnClickListener {
clickListener?.onItemClicked(outlet)
}
}
}
class OutletListAdapter(private var outletList: OutletListPOJODataClasses, private val itemClickListener: OutletListOnItemClickListener)
: RecyclerView.Adapter<OutletListItemHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OutletListItemHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.outlet_list_item_layout, parent, false)
return OutletListItemHolder(v)
}
override fun getItemCount(): Int = outletList.data!!.size
override fun onBindViewHolder(holder: OutletListItemHolder, position: Int) {
val outlet = outletList.data?.get(position)
if (outlet != null) {
holder.bind(outlet, itemClickListener)
}
}
}
interface OutletListOnItemClickListener{
fun onItemClicked(outlet: OutletListPOJODataClassesDataItem)
}
如何從 OutletListFragment.kt 中的數據OutletListFragment.kt
中獲取我想要的變量並將其傳遞給ProductListFragment.kt
? 如果有任何不清楚的地方,請告訴我。
編輯:
這是navigation.xml
的片段:
<fragment
android:id="@+id/productStockOutletList"
android:name="com.example.switchingandroidappproject.mainFragments.ProductStockOutletListFragment"
android:label="ProductStockOutletList" >
<action
android:id="@+id/action_productStockOutletList_to_productListFragment"
app:destination="@id/productListFragment"
app:enterAnim="@android:anim/slide_in_left"
app:exitAnim="@android:anim/slide_out_right"
app:popEnterAnim="@android:anim/slide_in_left"
app:popExitAnim="@anim/slide_out_left" />
</fragment>
<fragment
android:id="@+id/productListFragment"
android:name="com.example.switchingandroidappproject.mainFragments.ProductListFragment"
android:label="ProductListFragment" />
如果您使用的是 Jetpack Navigation(並且您指的是“導航圖”之類的東西,那么顯然您正在使用 Jetpack Navigation),那么要在導航目的地之間傳遞 arguments,您必須使用正確的arguments
定義一個<action
作為可打包數據的一些變體傳遞給另一個片段。
這是文檔中的示例:
<action android:id="@+id/startMyFragment" app:destination="@+id/myFragment"> <argument android:name="myArg" app:argType="integer" android:defaultValue="1" /> </action>
所以在你的情況下,它應該像你需要類似的東西
<navigation ...>
<action android:id="@+id/toProductListFragment"
app:destination="@+id/productListFragment">
<argument
android:name="stkProdcode"
app:argType="string" />
</action>
顯然,這些東西只有在您還啟用了safeargs
插件的情況下才有效(否則您必須自己“記住”這個密鑰,或者手動編寫NavDirections
class,或者自己組合Bundle
- 無論哪種方式,Jetpack Navigation 都希望您使用 Safeargs傳遞參數):
buildscript {
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.2"
和
apply plugin: "androidx.navigation.safeargs.kotlin"
然后你應該能夠做到
class OutletListFragment: Fragment(), OutletListOnItemClickListener {
....
override fun onItemClicked(outlet: OutletListPOJODataClassesDataItem) {
Navigation.findNavController(view).navigate(NavigationDirections.toProductListFragment(outlet.stkProdcode))
}
}
由於 Jetpack Navigation 的限制,您還必須將參數定義復制到<fragment
標記中:
<fragment
android:id="@+id/productListFragment"
android:name="com.example.switchingandroidappproject.mainFragments.ProductListFragment"
android:label="ProductListFragment" >
<argument
android:name="stkProdcode"
app:argType="string" />
</fragment>
確保不要打錯字( android:name
mismatch),因為你會遇到意外的失敗)。
現在您可以在另一邊獲得您的 arguments
val args = ProductListFragmentArgs.fromBundle(getArguments())
val code = args.stkProdcode
我並沒有真正使用 Jetpack Navigation,所以我很驚訝地看到您必須將片段 args 復制到動作 args,但是您已經有了。
...想想我用什么代替 Jetpack Navigation ,這很簡單
// send
backstack.goTo(ProductListScreen(stkProdCode))
// receive
val prodCode = getKey<ProductListScreen>().stkProdCode
並且是(如果不是更多的話)類型安全的。 *grumble* *grumble* 但這對你的情況沒有幫助,那不是 Jetpack Navigation。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.