切换按钮视图保留状态

问题描述

在我的应用程序片段之一中,布局使用一个定义为:

的切换按钮
<ToggleButton
    android:id="@+id/custom_toggle_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginStart="4dp"
    android:minWidth="110dp"
    android:minHeight="36dp"
    android:background="@drawable/toggle_button_bg_bw"
    android:textColor="@drawable/toggle_color_bw"
    android:textOff="@string/text_off"
    android:textOn="@string/text_on"
    android:textSize="12sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/stm"
    app:layout_constraintTop_toTopOf="parent" />

背景可绘制:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:drawable="@drawable/black_button_selected"
            android:state_checked="true" />
    <item
            android:drawable="@drawable/white_button_unselected" />
</selector>

black_button_selected:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >
    <stroke
            android:width="2dp"
            android:color="@color/colorGreen" />
    <solid
            android:color="@color/colorBlack" />
    <corners android:radius="3dp" />
</shape>

white_button_unselected:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >
    <stroke
            android:width="2dp"
            android:color="@color/colorGreen" />
    <solid
            android:color="@color/colorWhite" />
    <corners android:radius="3dp" />
</shape>

TextColor可绘制:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:state_checked="false"
            android:color="@color/colorBlack" />
    <item
            android:state_checked="true"
            android:color="@color/colorWhite" />
</selector>

在createView中,以下代码调用。 options_view包含其他按钮和视图元素,这些按钮和视图元素附加到editorView上,并且editorView是此片段布局的一部分。

optionsViewBinding = DataBindingUtil.inflate(
    inflater,R.layout.options_view,binding.editorView,true
)

optionsViewBinding.run {
    customToggleButton.isChecked = false
    customToggleButton.setonClickListener {
        someFunction(customToggleButton.isChecked)
    }
}

我面临的问题是,当我将开关切换到“开”并继续移动到其他片段,然后使用此切换按钮返回到片段时,切换按钮的状态已重置为“假” / OFF。状态,但显示的视图将其显示为“打开”状态。

在这里想念什么?

解决方法

您可以尝试一些不同的方法,但我不保证它们会起作用。
我个人试图避免在onCreateView中进行设置,因为并非总是在此处创建视图。问题可能是您在视图完全初始化之前更改了按钮的状态,然后它会覆盖ToggleButton的状态,因此您设置了某些状态并且视图错误。因此,将此行放在OnViewCreated中:

customToggleButton.isChecked = false
customToggleButton.setOnClickListener {
    someFunction(customToggleButton.isChecked)
}

此外,如果您在更改片段时可以保留toggleButton状态,则可以省略行下方,它应保持状态良好且背景显示正确:

customToggleButton.isChecked = false
,

我无法解决此问题,但是我已经能够找到一种替代方法,它可能不是最优雅的替代方法,但是它可以工作。

创建自定义按钮类:

class CustomToggleButton @JvmOverloads constructor(
    context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : AppCompatButton(context,attrs,defStyleAttr) {
    var isChecked = false
    var onOffResID = Array<Int>(2) { 0 }
    var onOffTextColorId = Array<Int>(2) { 0 }

    fun initButton() {
        // Should crash if resource ID invalid
        background = AppCompatResources.getDrawable(context,onOffResID[0])
        setTextColor(context.resources.getColor(onOffTextColorId[0]))
    }

    fun onClick() {
        isChecked = !isChecked
        val index = if (isChecked) 1 else 0
        background = AppCompatResources.getDrawable(context,onOffResID[index])
        setTextColor(context.resources.getColor(onOffTextColorId[index]))
    }
}

onCreateView或onViewCreated片段中

customToggleButton.onOffResID = arrayOf(R.drawable.white_button_unselected,R.drawable.black_button_selected)
customToggleButton.onOffTextColorId = arrayOf(R.color.colorBlack,R.color.colorWhite)
customToggleButton.initButton()
customToggleButton.setOnClickListener {
    customToggleButton.onClick()
    someFunction(customToggleButton.isChecked)
}