问题
I want to change the text in a TextView (id: dailyTotalTextView) in MainActivity, when I click a button in a RecyclerView. But I get an error saying dailyTotalTextView must not be null.
I have a basic knowledge of Kotlin and no Java experience, so I might be going all wrong about this.
The TextView displays the sum of values in a list. The list items contain a number and a button to delete the item. When I delete an item I want the TextView to change the total.
In MainActivity an item can be added to the list and by using .notifyDataSetChanged() I can set the text to the new value.
The DrinksToday object holds the variables and methods for changing the list.
The adapter holds the onClick for the delete button, so it can delete the item at the clicked position. This is also where I wanted to change the TextView.
MainActivity:
class MainActivity : AppCompatActivity() {
private lateinit var adapter: TodayDrinksRecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainTextDailyTotal.text = dailyTotal.toString()
adapter = TodayDrinksRecyclerAdapter(this, DrinksToday.drinksTodayList)
drinksTodayList.adapter = adapter
val layoutManager = LinearLayoutManager(this)
drinksTodayList?.layoutManager = layoutManager
}
fun addWaterClick(@Suppress("UNUSED_PARAMETER") view: View) {
DrinksToday.addDrink()
adapter.notifyDataSetChanged()
mainTextDailyTotal.text = dailyTotal.toString()
}
}
DrinksToday object:
object DrinksToday {
var currentGlass = Drinks("water01", "250", "ml")
var dailyTotal = 0
var drinksTodayList: MutableList<Drinks> = mutableListOf()
fun addDrink() {
dailyTotal += currentGlass.volume.toInt()
drinksTodayList.add(0, currentGlass)
}
fun removeDrink(position: Int) {
drinksTodayList.removeAt(position)
}
}
Edit: I changed the inner class Holder and now use kotlinx.android.synthetic to access the view references.
RecyclerAdapter:
class TodayDrinksRecyclerAdapter(private val context: Context, private val todaysDrinks: MutableList<Drinks>) :
RecyclerView.Adapter<TodayDrinksRecyclerAdapter.Holder>() {
// ... standard adapter code here: onBindViewHolder, getItemCount, onCreateViewHolder
open inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindDrinks(drinks: Drinks, context: Context) {
itemView.drinkListText.text = drinks.volume
itemView.drinkListButtonDelete.setOnClickListener {
val position = adapterPosition
DrinksToday.removeDrink(position)
DrinksToday.dailyTotal -= drinks.volume.toInt()
notifyDataSetChanged()
val dailyTotalTextView = itemView.findViewById<TextView>(R.id.mainTextDailyTotal)
dailyTotalTextView.text = DrinksToday.dailyTotal.toString()
}
}
}
}
TextView XML:
<TextView
android:id="@+id/mainTextDailyTotal"
android:text="0"
android:layout_width="0dp"
android:layout_height="0dp"/>
When I run this code I get an error saying:
java.lang.IllegalStateException: dailyTotalTextView must not be null at adapters.TodayDrinksRecyclerAdapter$Holder$bindDrinks$1.onClick(TodayDrinksRecyclerAdapter.kt:54)
Which refers to is this line of code:
val dailyTotalTextView = itemView.findViewById<TextView>(R.id.mainTextDailyTotal)
I don't understand why this TextView is Null. I would expect this to work. Hopefully someone can help me out.
回答1:
I got it figured out, thanks to the reply of Lalit Behera and some research.
I added this interface to my RecylerAdapter:
interface OnItemClickListener {
fun onItemClick(dailyTotal: Int)
}
Changed the constructor of the RecyclerAdapter by adding an OnItemClickListener:
class TodayDrinksRecyclerAdapter(private val context: Context, private val todayDrinks: MutableList<Drinks>,
private var onItemClickListener: OnItemClickListener)
And to the setOnClickListenr in the class Holder I added:
itemView.drinkListButtonDelete.setOnClickListener {
val position = adapterPosition
DrinksToday.removeDrink(position)
dailyTotal -= drinks.volume.toInt()
notifyDataSetChanged()
// added this line
onItemClickListener.onItemClick(dailyTotal)
}
Then in MainActivity my adapter became:
adapter = TodayDrinksRecyclerAdapter(this, DrinksToday.drinksTodayList, object : TodayDrinksRecyclerAdapter.OnItemClickListener {
override fun onItemClick(dailyTotal: Int) {
mainTextDailyTotal.text = dailyTotal.toString()
}
})
来源:https://stackoverflow.com/questions/56405975/change-textview-in-mainactvity-from-recycleradapter-using-kotlin