Change TextView in MainActvity from RecyclerAdapter using Kotlin

只谈情不闲聊 提交于 2020-01-15 09:11:24

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!