Search code examples
androidkotlincolor-picker

Android: colorPicker setButtonOkText not worked


I have a color picker but I need to change text setButtonOkText(R.string.accept) or setButtonCancelText(R.string.cancel) but not work only color picker used default ok and cancel and can change background pallet color? or set typeface for ok cancel texts?

  <resources>
    <string name="cancel">Close</string>
    <string name="accept">Accept</string>
    </resources>

        val colorPicker=ColorPickerDialog.Builder()
            .setInitialColor(Color.BLACK)
            .setColorModel(ColorModel.HSV)
            .setColorModelSwitchEnabled(true)
            .setButtonOkText(R.string.accept)
            .setButtonCancelText(R.string.cansel)
            .onColorSelected { color: Int ->

            }
            .create()
        colorPicker.show(supportFragmentManager, "color_picker")

color picker


Solution

  • Update 2022

    This bug was fixed in version 1.0.3, so now you just need to update the dependency

    implementation 'io.github.vadiole:colorpicker:1.0.3'
    

    Old answer

    Unfortunately the library looks like it has a bug.

    The positive and negative buttons never have their text set to the passed in ids.

    https://github.com/vadiole/colorpicker/blob/master/colorpicker/src/main/java/vadiole/colorpicker/ColorPickerView.kt

    Look at lines 201 and 202 this is the only time these 2 buttons are pulled and neither of them call setText. The xml shows they are hardcoded to default strings.

    Luckily there may be a workaround in here,

    https://github.com/vadiole/colorpicker/blob/master/colorpicker/src/main/java/vadiole/colorpicker/ColorPickerDialog.kt

    You will need to override two classes ColorPickerView and ColorPickerDialog

    ColorPickerView will only need you to provide a modified constructor. Call it FixedColorPickerView

    constructor(
        context: Context,
        actionOkRes: Int,
        actionCancelRes: Int,
        @ColorInt initialColor: Int = Color.DKGRAY,
        colorModel: ColorModel,
        colorModelSwitchEnabled: Boolean,
        onSwitchColorModelListener: OnSwitchColorModelListener? = null,
    ) : super(context,
              actionOkRes,
              actionCancelRes,
              initialColor,
              colorModel,
              colorModelSwitchEnabled,
              onSwitchColorModelListener) {
                //Your constructor will simply grab the buttons and set their texts 
                //after the real constructor has inited view.
                val positiveButton = findViewById<Button>(R.id.positive_button)
                val negativeButton = findViewById<Button>(R.id.negative_button)
                positiveButton.setText(actionOkRes)
                negativeButton.setText(actionCancelRes)
    }
    

    ColorPickerDialog you need to override 2 methods

    onCreateDialog to replace theColorPickerView its creating.

    onSaveInstanceState to avoid a NPE due to the reference to the old ColorPickerView

    class FixedColorPickerDialog : ColorPickerDialog {
        var fixPickerView: ColorPickerView by Delegates.notNull()
    
        override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
            val bundle = savedInstanceState ?: arguments!!
            val actionOk = bundle.getInt(ACTION_OK_KEY)
            val actionCancel = bundle.getInt(ACTION_CANCEL_KEY)
    
            fixPickerView =
                FixedColorPickerView(
                    requireContext(),
                    actionOk,
                    actionCancel,
                    bundle.getInt(INITIAL_COLOR_KEY),
                    ColorModel.fromName(bundle.getString(COLOR_MODEL_NAME_KEY)),
                    bundle.getBoolean(COLOR_MODEL_SWITCH_KEY),
                    onSwitchColorModelListener
                )
    
            fixPickerView.enableButtonBar(
                object : ColorPickerView.ButtonBarListener {
                    override fun onNegativeButtonClick() = dismiss()
                    override fun onPositiveButtonClick(color: Int) {
                        onSelectColorListener?.onColorSelected(color)
                        dismiss()
                    }
                }
            )
    
            return AlertDialog.Builder(requireContext()).setView(fixPickerView).create()
        }
        override fun onSaveInstanceState(outState: Bundle) {
            val bundle =
                makeArgs(
                    fixPickerView.actionOkRes,
                    fixPickerView.actionCancelRes,
                    fixPickerView.currentColor,
                    fixPickerView.colorModel,
                    fixPickerView.colorModelSwitchEnabled
                )
            outState.putAll(bundle)
            super.onSaveInstanceState(outState)
        }
    }