簡體   English   中英

用視圖綁定替換 kotlin 合成后應用程序強制關閉

[英]App is force closing after replacing kotlin synthetics with view binding

我試圖了解有關 android 的新知識,但是當我將項目更改為使用視圖綁定時,應用程序強制在啟動時關閉。 找出導致強制關閉問題的原因對我來說將是一個非常大的幫助。

這是 MainActivity.kt 代碼

class MainActivity : AppCompatActivity() {
private val TAG = "MainActivity"

//You can ignore this messageList if you're coming from the tutorial,
// it was used only for my personal debugging
var messagesList = mutableListOf<Message>()

private lateinit var adapter: MessagingAdapter
private val botList = listOf("Peter" , "Peter" , "Peter" , "Peter")
private lateinit var binding: ActivityMainBinding


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    recyclerView()

    clickEvents()

    val random = (0..3).random()
    customBotMessage("Hello! Today you're speaking with ${botList[random]}, how may I help?")
}

private fun clickEvents() {

    //Send a message
    binding.btnSend.setOnClickListener {
        sendMessage()
    }

    //Scroll back to correct position when user clicks on text view
    binding.etMessage.setOnClickListener {
        GlobalScope.launch {
            delay(100)

            withContext(Dispatchers.Main) {
                binding.rvMessages.scrollToPosition(adapter.itemCount - 1)

            }
        }
    }
}

private fun recyclerView() {
    adapter = MessagingAdapter()
    binding.rvMessages.adapter = adapter
    binding.rvMessages.layoutManager = LinearLayoutManager(applicationContext)

}

override fun onStart() {
    super.onStart()
    //In case there are messages, scroll to bottom when re-opening app
    GlobalScope.launch {
        delay(100)
        withContext(Dispatchers.Main) {
            binding.rvMessages.scrollToPosition(adapter.itemCount - 1)
        }
    }
}

private fun sendMessage() {
    val message = binding.etMessage.text.toString()
    val timeStamp = Time.timeStamp()

    if (message.isNotEmpty()) {
        //Adds it to our local list
        messagesList.add(Message(message, SEND_ID, timeStamp))
        binding.etMessage.setText("")

        adapter.insertMessage(Message(message, SEND_ID, timeStamp))
        binding.rvMessages.scrollToPosition(adapter.itemCount - 1)

        botResponse(message)
    }
}

private fun botResponse(message: String) {
    val timeStamp = Time.timeStamp()

    GlobalScope.launch {
        //Fake response delay
        delay(1000)

        withContext(Dispatchers.Main) {
            //Gets the response
            val response = BotResponse.basicResponses(message)

            //Adds it to our local list
            messagesList.add(Message(response, RECEIVE_ID, timeStamp))

            //Inserts our message into the adapter
            adapter.insertMessage(Message(response, RECEIVE_ID, timeStamp))

            //Scrolls us to the position of the latest message
            binding.rvMessages.scrollToPosition(adapter.itemCount - 1)

            //Starts Google
            when (response) {
                OPEN_GOOGLE -> {
                    val site = Intent(Intent.ACTION_VIEW)
                    site.data = Uri.parse("https://www.google.com/")
                    startActivity(site)
                }
                OPEN_SEARCH -> {
                    val site = Intent(Intent.ACTION_VIEW)
                    val searchTerm: String? = message.substringAfterLast("search")
                    site.data = Uri.parse("https://www.google.com/search?&q=$searchTerm")
                    startActivity(site)
                }

            }
        }
    }
}

private fun customBotMessage(message: String) {

    GlobalScope.launch {
        delay(1000)
        withContext(Dispatchers.Main) {
            val timeStamp = Time.timeStamp()
            messagesList.add(Message(message, RECEIVE_ID, timeStamp))
            adapter.insertMessage(Message(message, RECEIVE_ID, timeStamp))

            binding.rvMessages.scrollToPosition(adapter.itemCount - 1)
        }
    }
}

}

這是 MessagingAdapter.kt 文件

class MessagingAdapter: RecyclerView.Adapter<MessagingAdapter.MessageViewHolder>() {

var messagesList = mutableListOf<Message>()
private lateinit var binding: MessageItemBinding

inner class MessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    init {
        itemView.setOnClickListener {

            //Remove message on the item clicked
            messagesList.removeAt(adapterPosition)
            notifyItemRemoved(adapterPosition)
        }
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {

    return MessageViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.message_item, parent, false)
    )
}

override fun getItemCount(): Int {
    return messagesList.size
}

@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
    val currentMessage = messagesList[position]


    when (currentMessage.id) {
        SEND_ID -> {
            holder.itemView.findViewById<View>(R.id.tv_message).apply {
                binding.tvMessage.text = currentMessage.message
                visibility = View.VISIBLE
            }
            holder.itemView.findViewById<View>(R.id.tv_bot_message).visibility = View.GONE
        }
        RECEIVE_ID -> {
            holder.itemView.findViewById<View>(R.id.tv_bot_message).apply {
                binding.tvBotMessage.text = currentMessage.message
                visibility = View.VISIBLE
            }
            holder.itemView.findViewById<View>(R.id.tv_message).visibility = View.GONE
        }
    }
}

fun insertMessage(message: Message) {
    this.messagesList.add(message)
    notifyItemInserted(messagesList.size)
}

}

如果你能幫我解決這個問題,那將是一個非常大的幫助。

這是一個可能適合您的MessagingAdapter的基本布局。 然后在onBindViewHolder ,您可以使用holder.binding.viewId訪問您的視圖。 您可以根據需要進行調整。

class MessagingAdapter(var messagesList: List<Message>) : 
    RecyclerView.Adapter<MessagingAdapter.MessageViewHolder>() {

    inner class MessageViewHolder(val binding: MessageItemBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
        val view =
            MessageItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MessageViewHolder(view)
    }
    //other required implementations
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM