如何访问片段中 Recycler View 中每个项目的共享首选项
How to access Shared Preferences for each item in Recycler View in Fragment
我想将 Button 的共享首选项存储在 Fragment 使用的 Recycler View Adapter 中。
class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
private val name = arrayOf("Android Dev W1",
"Android Dev W2", "Web Dev W1", "Learn Kotlin B1",
"Android Dev W3", "Android Dev W4", "Web Dev W2",
"Learn DSA")
private val date = arrayOf("20:00 18th May, 2021", "04:00 18th May, 2021",
"07:00 19th May, 2021", "04:00 20th May, 2021",
"01:00 21th May, 2021", "10:00 21th May, 2021",
"20:00 27th May, 2021", "10:00 30th May, 2021")
private val btn = arrayOf(false, false, false, false, false, false, false, false)
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var itemName: TextView = itemView.findViewById(R.id.workshopName)
var itemDate: TextView = itemView.findViewById(R.id.workshopDate)
var button: Button = itemView.findViewById(R.id.applyBtn)
val prefs = itemView.context.getSharedPreferences("prefs", MODE_PRIVATE)
init {
for(i in 0 .. 7) {
//checking via sharedPreferences if this app is being run first time or not
btn[i] = prefs.getBoolean("registered$i", false)
if (btn[i]) {
hideButton()
} else {
showButton()
}
}
}
fun hideButton() {
button.text = "Applied"
button.isClickable = false
button.setBackgroundColor(Color.parseColor("#FF3700E9"))
}
private fun showButton() {
button.text = "Apply"
button.isClickable = true
button.setBackgroundColor(Color.parseColor("#FF6200EE"))
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
val v = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.frame_textview, viewGroup, false)
return ViewHolder(v)
}
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.itemName.text = name[i]
viewHolder.itemDate.text = date[i]
viewHolder.button.setOnClickListener {
viewHolder.prefs.edit().putBoolean("registered$i", true).apply()
btn[i] = true
viewHolder.hideButton()
}
}
override fun getItemCount(): Int {
return name.size
}
}
正在使用此适配器的片段
class AvailableWorkshops : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_available_workshops, container, false)
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
val recyclerView = itemView.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = RecyclerViewAdapter()
}
}
}
例如,此适配器中有 8 个项目,我单击第 5 个项目,它将调用 onClickListener() 并更改按钮 属性,这完全没问题。
但是,当我们重新启动应用程序时,它会变回默认按钮属性(共享首选项不起作用)
同样,如果我单击每个项目并重新启动应用程序,它现在将显示每个项目的新更改(共享首选项在这里起作用)。
我想存储如果我点击第 5 个项目,然后在应用程序重新启动时它应该只更改第 5 个项目的显示,而不是每个项目。
I want to store that if I click on 5th Item, then on app restart it should change display of only 5th item, not for every item.
你的问题
一个ViewHolder
表示RecyclerView
中的一项。当您初始化 ViewHolder
时,您将首选项应用了 7 次 到同一个按钮 。
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//...
init {
// ** THIS IS NOT HIDING OR SHOWING SEVEN DIFFERENT BUTTONS - THIS IS HIDING OR
// SHOWING THIS VIEWHOLDER'S ONE BUTTON SEVEN TIMES **
for(i in 0 .. 7) {
//checking via sharedPreferences if this app is being run first time or not
btn[i] = prefs.getBoolean("registered$i", false)
if (btn[i]) {
hideButton()
} else {
showButton()
}
}
}
一个解决方案
删除 ViewHolder
中的 init
块,并将隐藏/显示逻辑移动到 onBindViewHolder
方法,在该方法中设置 每个实例.
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.itemName.text = name[i]
viewHolder.itemDate.text = date[i]
// ** SHOW OR HIDE THIS INSTANCE'S BUTTON - AND ONLY THIS INSTANCE'S BUTTON **
if (viewHolder.prefs.getBoolean("registered$i", false)) {
viewHolder.hideButton()
} else {
viewHolder.showButton()
}
viewHolder.button.setOnClickListener {
viewHolder.prefs.edit().putBoolean("registered$i", true).apply()
btn[i] = true
viewHolder.hideButton()
}
}
我想将 Button 的共享首选项存储在 Fragment 使用的 Recycler View Adapter 中。
class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
private val name = arrayOf("Android Dev W1",
"Android Dev W2", "Web Dev W1", "Learn Kotlin B1",
"Android Dev W3", "Android Dev W4", "Web Dev W2",
"Learn DSA")
private val date = arrayOf("20:00 18th May, 2021", "04:00 18th May, 2021",
"07:00 19th May, 2021", "04:00 20th May, 2021",
"01:00 21th May, 2021", "10:00 21th May, 2021",
"20:00 27th May, 2021", "10:00 30th May, 2021")
private val btn = arrayOf(false, false, false, false, false, false, false, false)
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var itemName: TextView = itemView.findViewById(R.id.workshopName)
var itemDate: TextView = itemView.findViewById(R.id.workshopDate)
var button: Button = itemView.findViewById(R.id.applyBtn)
val prefs = itemView.context.getSharedPreferences("prefs", MODE_PRIVATE)
init {
for(i in 0 .. 7) {
//checking via sharedPreferences if this app is being run first time or not
btn[i] = prefs.getBoolean("registered$i", false)
if (btn[i]) {
hideButton()
} else {
showButton()
}
}
}
fun hideButton() {
button.text = "Applied"
button.isClickable = false
button.setBackgroundColor(Color.parseColor("#FF3700E9"))
}
private fun showButton() {
button.text = "Apply"
button.isClickable = true
button.setBackgroundColor(Color.parseColor("#FF6200EE"))
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
val v = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.frame_textview, viewGroup, false)
return ViewHolder(v)
}
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.itemName.text = name[i]
viewHolder.itemDate.text = date[i]
viewHolder.button.setOnClickListener {
viewHolder.prefs.edit().putBoolean("registered$i", true).apply()
btn[i] = true
viewHolder.hideButton()
}
}
override fun getItemCount(): Int {
return name.size
}
}
正在使用此适配器的片段
class AvailableWorkshops : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_available_workshops, container, false)
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
val recyclerView = itemView.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = RecyclerViewAdapter()
}
}
}
例如,此适配器中有 8 个项目,我单击第 5 个项目,它将调用 onClickListener() 并更改按钮 属性,这完全没问题。
但是,当我们重新启动应用程序时,它会变回默认按钮属性(共享首选项不起作用)
同样,如果我单击每个项目并重新启动应用程序,它现在将显示每个项目的新更改(共享首选项在这里起作用)。
我想存储如果我点击第 5 个项目,然后在应用程序重新启动时它应该只更改第 5 个项目的显示,而不是每个项目。
I want to store that if I click on 5th Item, then on app restart it should change display of only 5th item, not for every item.
你的问题
一个ViewHolder
表示RecyclerView
中的一项。当您初始化 ViewHolder
时,您将首选项应用了 7 次 到同一个按钮 。
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//...
init {
// ** THIS IS NOT HIDING OR SHOWING SEVEN DIFFERENT BUTTONS - THIS IS HIDING OR
// SHOWING THIS VIEWHOLDER'S ONE BUTTON SEVEN TIMES **
for(i in 0 .. 7) {
//checking via sharedPreferences if this app is being run first time or not
btn[i] = prefs.getBoolean("registered$i", false)
if (btn[i]) {
hideButton()
} else {
showButton()
}
}
}
一个解决方案
删除 ViewHolder
中的 init
块,并将隐藏/显示逻辑移动到 onBindViewHolder
方法,在该方法中设置 每个实例.
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.itemName.text = name[i]
viewHolder.itemDate.text = date[i]
// ** SHOW OR HIDE THIS INSTANCE'S BUTTON - AND ONLY THIS INSTANCE'S BUTTON **
if (viewHolder.prefs.getBoolean("registered$i", false)) {
viewHolder.hideButton()
} else {
viewHolder.showButton()
}
viewHolder.button.setOnClickListener {
viewHolder.prefs.edit().putBoolean("registered$i", true).apply()
btn[i] = true
viewHolder.hideButton()
}
}