android 打印按钮的 selector 状态

本文深入探讨了在Android开发中,如何使用onKeyDown和onKeyUp方法来监听按键事件,并记录了按钮的各种状态,如启用、聚焦、按下、激活、可点击、悬停和触摸模式。这对于理解用户交互和优化应用程序响应性至关重要。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    Log.e(TAG, "onKeyDown isEnabled " + pressButton.isEnabled() + ", isFocused " + pressButton.isFocused() + ",isPressed " + pressButton.isPressed()
            + ",isActivated " + pressButton.isActivated() + ",isClickable " + pressButton.isClickable()+ ",isHovered " +pressButton.isHovered()+ ",isInTouchMode " +pressButton.isInTouchMode());
    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    Log.e(TAG, "onKeyUp isEnabled " + pressButton.isEnabled() + ", isFocused " + pressButton.isFocused() + ",isPressed " + pressButton.isPressed()
            + ",isActivated " + pressButton.isActivated() + ",isClickable " + pressButton.isClickable()+ ",isHovered " +pressButton.isHovered()+ ",isInTouchMode " +pressButton.isInTouchMode());
    return super.onKeyUp(keyCode, event);
}

 

com.example.bulbpage.editpreset import android.content.res.ColorStateList import android.graphics.Color import androidx.fragment.app.viewModels import android.os.Bundle import android.util.Log import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import androidx.core.content.ContextCompat import com.example.bulbpage.R import com.example.bulbpage.databinding.FragmentEditPresetBinding class EditPresetFragment : Fragment() { private var _binding: FragmentEditPresetBinding? = null private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentEditPresetBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 默认选中 A binding.buttonA.isChecked = true binding.optionGroup.addOnButtonCheckedListener { group, checkedId, isChecked -> if (!isChecked) return@addOnButtonCheckedListener when (checkedId) { R.id.buttonA -> { Log.d("Click", "ClickA") binding.buttonA.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonA.setTextColor(Color.WHITE) binding.buttonB.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonB.setTextColor(Color.BLACK) } R.id.buttonB -> { Log.d("Click", "ClickB") binding.buttonB.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonB.setTextColor(Color.WHITE) binding.buttonA.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonA.setTextColor(Color.BLACK) } } } } override fun onDestroyView() { super.onDestroyView() _binding = null } } <androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android” xmlns:tools=“http://schemas.android.com/tools” android:layout_width=“match_parent” android:layout_height=“match_parent” xmlns:app=“http://schemas.android.com/apk/res-auto” tools:context=“.editpreset.EditPresetFragment”> <ImageView android:id="@+id/imageView3" android:layout_width="24dp" android:layout_height="24dp" android:scaleType="centerInside" android:src="@drawable/close" android:layout_marginStart="16dp" app:layout_constraintBottom_toBottomOf="@+id/edit_auto_white" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/edit_auto_white" /> <TextView android:id="@+id/edit_auto_white" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:text="Edit Auto White" android:textSize="20dp" app:layout_constraintStart_toEndOf="@+id/imageView3" app:layout_constraintTop_toTopOf="parent"> </TextView> <ImageView android:layout_width="24dp" android:layout_height="24dp" android:scaleType="centerInside" android:src="@drawable/ok" android:layout_marginEnd="16dp" app:layout_constraintBottom_toBottomOf="@+id/edit_auto_white" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/edit_auto_white" app:layout_constraintVertical_bias="1.0" /> <!-- res/layout/fragment_tab_selector.xml --> <androidx.cardview.widget.CardView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" app:cardCornerRadius="50dp" app:cardElevation="4dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/edit_auto_white"> <com.google.android.material.button.MaterialButtonToggleGroup android:id="@+id/optionGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:selectionRequired="true"> <com.google.android.material.button.MaterialButton android:id="@+id/buttonA" android:layout_width="120dp" android:layout_height="48dp" android:text="A" android:checkable="true" android:checked="true" app:backgroundTint="@android:color/white" app:rippleColor="@android:color/transparent" /> <com.google.android.material.button.MaterialButton android:id="@+id/buttonB" android:layout_width="120dp" android:layout_height="48dp" android:text="B" android:checkable="true" app:backgroundTint="@android:color/white" app:rippleColor="@android:color/transparent" /> </com.google.android.material.button.MaterialButtonToggleGroup> </androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>只有最开始会打印点击事件,后面点击时不会触发点击
08-26
你遇到的问题是: > **只有第一次点击按钮时会触发 `addOnButtonCheckedListener`,后续点击不再触发** --- ### 🔍 原因分析 #### 1. **`binding.buttonA.isChecked = true` 被重复设置** - 你在 `onViewCreated` 中设置了 `binding.buttonA.isChecked = true`,而 XML 中已经设置了 `android:checked="true"`。 - 这可能导致 `MaterialButtonToggleGroup` 认为按钮状态未变化,从而不触发监听器。 #### 2. **在点击事件中修改了按钮的 `checkable` 状态** - 如果你在点击时修改了按钮的 `checkable` 属性(如设为 `false`),或按钮状态未正确更新,后续点击将不会触发监听器。 #### 3. **监听器被多次设置或绑定错误** - 如果你多次设置了 `addOnButtonCheckedListener`,或者监听器绑定到了错误的 `MaterialButtonToggleGroup`,也可能导致事件无法正常触发。 --- ### ✅ 解决方案 #### ✅ 1. **移除重复设置的 `isChecked = true`** ```kotlin override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 已在 XML 中默认选中 A,无需重复设置 // binding.buttonA.isChecked = true // 删除这行 binding.optionGroup.addOnButtonCheckedListener { group, checkedId, isChecked -> if (!isChecked) return@addOnButtonCheckedListener when (checkedId) { R.id.buttonA -> { Log.d("Click", "ClickA") binding.buttonA.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonA.setTextColor(Color.WHITE) binding.buttonB.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonB.setTextColor(Color.BLACK) } R.id.buttonB -> { Log.d("Click", "ClickB") binding.buttonB.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonB.setTextColor(Color.WHITE) binding.buttonA.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonA.setTextColor(Color.BLACK) } } } } ``` #### ✅ 2. **确保按钮始终是 `checkable` 的** ```xml <com.google.android.material.button.MaterialButton android:id="@+id/buttonA" android:layout_width="120dp" android:layout_height="48dp" android:text="A" android:checkable="true" android:checked="true" android:textColor="@android:color/black" app:backgroundTint="@android:color/white" app:rippleColor="@android:color/transparent" /> <com.google.android.material.button.MaterialButton android:id="@+id/buttonB" android:layout_width="120dp" android:layout_height="48dp" android:text="B" android:checkable="true" android:textColor="@android:color/black" app:backgroundTint="@android:color/white" app:rippleColor="@android:color/transparent" /> ``` #### ✅ 3. **不要在点击事件中修改按钮的 `checkable` 状态** - 确保你的逻辑中没有 `button.isCheckable = false` 或类似操作。 #### ✅ 4. **确保监听器只添加一次** - 如果你在 `onViewCreated` 中多次添加监听器,会导致冲突。 --- ### ✅ 推荐做法:初始化样式 + 保证监听器正确绑定 ```kotlin override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 初始化按钮样式 resetButtonStyles() binding.optionGroup.addOnButtonCheckedListener { group, checkedId, isChecked -> if (!isChecked) return@addOnButtonCheckedListener when (checkedId) { R.id.buttonA -> { binding.buttonA.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonA.setTextColor(Color.WHITE) binding.buttonB.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonB.setTextColor(Color.BLACK) } R.id.buttonB -> { binding.buttonB.backgroundTintList = ColorStateList.valueOf( ContextCompat.getColor(requireContext(), R.color.skyblue) ) binding.buttonB.setTextColor(Color.WHITE) binding.buttonA.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonA.setTextColor(Color.BLACK) } } } } private fun resetButtonStyles() { binding.buttonA.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonA.setTextColor(Color.BLACK) binding.buttonB.backgroundTintList = ColorStateList.valueOf(Color.WHITE) binding.buttonB.setTextColor(Color.BLACK) } ``` --- ### ✅ 总结 | 问题 | 原因 | 解决方法 | |------|------|----------| | 点击事件只触发一次 | 重复设置 `isChecked = true` | 删除重复设置 | | 点击无响应 | 按钮 `checkable` 状态被修改 | 确保始终为 `true` | | 事件未绑定 | 监听器被覆盖或未正确添加 | 检查监听器是否只添加一次 | | 初始样式错误 | 未初始化按钮样式 | 添加 `resetButtonStyles()` | --- ### 🛠️ 调试建议 - 使用 `Log.d("State", "Button A is checked: ${binding.buttonA.isChecked}")` 打印按钮状态。 - 使用 `binding.optionGroup.checkedButtonId` 查看当前选中按钮 ID。 - 使用 Layout Inspector 检查按钮是否被禁用或不可点击。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值