在 android(Kotlin) 中单击时如何引用按钮视图?

How to refer to the button view when clicked on in android(Kotlin)?

这就是我指的按钮:

   <Button
    android:id="@+id/btnBR"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="4dp"
    android:layout_marginEnd="4dp"
    android:backgroundTint="#e6ebf2"
    android:onClick="setLetter"
    app:layout_constraintBottom_toBottomOf="@+id/btnBM"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/btnBM"
    app:layout_constraintTop_toBottomOf="@+id/btnMR" />

在我的 MainActivity 文件中,我试图创建一个函数来更改单击它的按钮的文本。我有 9 个不同的按钮(试图制作井字游戏),它们都需要相同的功能。

    package brianmason.example.tictactoe

    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.view.View
    import brianmason.example.tictactoe.databinding.ActivityMainBinding

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

        }
        fun setLetter(view: View){
            //Trying to do the equivalent of this.setText("X") however this seems to be referring to the MainActivity and not the view. view.setText("X") also does not work.
        }
    }

在使用setText函数时如何引用被点击的按钮?

声明一个变量private var player1Turn = true,我们将使用这个变量来检查轮到谁,并相应地在按钮上标记“X”和“O”。

按如下方式在每个按钮上设置onClickListner

binding.button1.setOnClickListner{
    if(button1.text != "") return@setOnClickListener
    else if(player1Turn) {
        button1.text = "X"
        player1Turn = !player1turn
    }
    else {
      button1.text = "O"
      player1Turn = !player1turn
    }
}

注意:我对玩家 1 使用“X”,对玩家 2 使用“O”。
让我知道它是否有效。

您可以将 view 转换为 Button,然后设置文本。 像这样:

fun setLetter(view: View){
        (view as Button).text = "X"
}

或者,您也可以这样做。在 xml 布局中,将所有按钮中的 onClick 属性更改为以下内容并添加数据标记:

<data>
        <variable name="mainViewModel"
                  type="com.example.yourappname.MainViewModel"/> <!-- The path to your ViewModel class> 
</data>

<!-- The parameter of handleClick function takes a value to identify each button. Makes sure it is unique for each button -->
<Button
        ...
        <!--The 1 donates the unique parameter to identify the button -->
        android:onClick='@{() -> mainViewModel.handleClick("1")}'/>

<Button
        ...
        android:onClick='@{() -> mainViewModel.handleClick("2")}'/>

然后创建一个 ViewModel 来处理点击:

class MainViewModel: ViewModel() {

        //private data so that we can only modify it inside this class 
        private val _buttonText = MutableLiveData<String>()

        //exposable data so that we can observe its changes later
        val buttonText = _buttonText as LiveData<String>
        
        /**
         *This is the function that will handle the clicks from the layout
         **/
        fun handleClick(string: String) {
            when (string) {
             // the value for buttonText can be anything here
                "1" -> _buttonText.value = "Button One clicked"  //Can be "X"
                "2" -> _buttonText.value = "Button Two clicked"   //Can be "O"
                "3" -> _buttonText.value = "Button Three clicked"  //etc
                "4" -> _buttonText.value = "Button Four clicked"
                 ...
                 ...
        }
    }
}

现在在 MainActivity 的 onCreate 方法中,添加以下内容

 class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val binding =  DataBindingUtil.setContentView<ActivityMainBinding>(this@MainActivity, R.layout.activity_main)

            //Get the ViewModel
            val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)

            binding.mainViewModel = mainViewModel    //Bind the ViewModel
            binding.lifecycleOwner = viewLifecycleOwner //Set the lifecycleOwner
             
            //Observe the change made to the buttonText in the ViewModel and display its value as a Toast
            mainViewModel.buttonText.observe(viewLifecycleOwner, {
                Toast.makeText(this@MainActivity, it, Toast.LENGTH_SHORT).show()

            //You can also modify the button text here

        })



        }
}