微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

首选项中的自定义DatePicker和TimePicker与“活动”中的不匹配

如何解决首选项中的自定义DatePicker和TimePicker与“活动”中的不匹配

我正在实现自定义TimePicker,用于在PreferenceFragmentCompat片段中设置首选项,主要遵循this指南。当我成功使之工作时,对话框的大小与另一个活动中相同对话框的大小并不相同。

对于TimePickerPreferenceFragmentCompat中的一个看起来像这样

TimePicker in PreferenceFragmentCompat

如果我将TimePicker放在其他任何活动中,外观都是

TimePicker in Activity

对于DatePicker,片段中的结果看起来像this question中的片段,并且在那里提出的解决方案不适用于我的情况。

是否可以让PreferenceFragment中的选择器看起来像“活动”中的选择器?我的实现如下:

styles.xml

<style name="Preference.App.DialogPreference" parent="Preference.Material">
    <item name="positiveButtonText">@android:string/ok</item>
    <item name="negativeButtonText">@android:string/cancel</item>
    <item name="android:dialogTitle" />
</style>

SettingsActivity.kt

class SettingsActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_preferences)
        supportFragmentManager.beginTransaction().replace(R.id.container,SettingsFragment())
            .commit()
    }

    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?,rootKey: String?) {
            setPreferencesFromresource(R.xml.preferences,rootKey)
        }
    
    
        override fun ondisplayPreferenceDialog(preference: Preference) {
            // Try if the preference is one of our custom Preferences
            val dialogFragment: DialogFragment? = when (preference) {
                is TimePickerPreference -> {
                    // Create a new instance of TimePreferenceDialogFragment with the key of the related
                    // Preference
                    TimePickerPreferenceDialog.newInstance(preference.getKey())
                }
                else -> null
            }

            if (dialogFragment != null) {
                // The dialog was created (it was one of our custom Preferences),show the dialog for it
                dialogFragment.setTargetFragment(this,0)
                dialogFragment.show(
                    parentFragmentManager,"androidx.preference.PreferenceFragmentCompat.DIALOG"
                )
            } else {
                // Dialog creation Could not be handled here. Try with the super method.
                super.ondisplayPreferenceDialog(preference)
            }
        }
    }
}

TimePickerPreference.kt

class TimePickerPreference @JvmOverloads constructor(
    context: Context?,attrs: AttributeSet? = null,defStyleAttr: Int = R.attr.preferenceStyle,defStyleRes: Int = defStyleAttr
) : DialogPreference(context,attrs,defStyleAttr,defStyleRes) {

    companion object {
        private const val DEFAULT_VALUE = 0
    }

    var time: Int = DEFAULT_VALUE
        set(value) {
            field = value
            // Save to SharedPreferences
            persistInt(value)
        }

    override fun onGetDefaultValue(a: TypedArray?,index: Int): Any? {
        // Default value from attribute. Fallback value is set to 0.
        return a?.getInt(index,DEFAULT_VALUE) ?: DEFAULT_VALUE
    }

    override fun onSetinitialValue(defaultValue: Any?) {
        // Read the value. Use the default value if it is not possible.
        time = getPersistedInt((defaultValue as? Int) ?: DEFAULT_VALUE)
        val hour = time / 60
        val minute = time % 60
        summary = "$hour:${if (minute < 10) "0$minute" else "$minute"}"
    }
}

TimePickerPreferenceDialog.kt

class TimePickerPreferenceDialog : PreferenceDialogFragmentCompat() {

    private lateinit var timePicker: TimePicker

    override fun onCreateDialogView(context: Context?): View {
        timePicker = TimePicker(context)
        return timePicker
    }

    override fun onBindDialogView(view: View?) {
        super.onBindDialogView(view)

        // Get the time from the related Preference
        val minutesAfterMidnight: Int = preference.time

        // Set the time to the TimePicker
        val hours = minutesAfterMidnight / 60
        val minutes = minutesAfterMidnight % 60
        val is24hour = DateFormat.is24HourFormat(context)

        timePicker.apply {
            setIs24HourView(is24hour)
            if (Build.VERSION.SDK_INT >= 23) {
                hour = hours
                minute = minutes
            } else {
                @Suppress("DEPRECATION")
                currentHour = hours
                @Suppress("DEPRECATION")
                currentMinute = minutes
            }
        }
    }

    override fun onDialogClosed(positiveResult: Boolean) {
        if (positiveResult) {
            val hours: Int
            val minutes: Int
            // Get the current values from the TimePicker
            if (Build.VERSION.SDK_INT >= 23) {
                hours = timePicker.hour
                minutes = timePicker.minute
            } else {
                @Suppress("DEPRECATION")
                hours = timePicker.currentHour
                @Suppress("DEPRECATION")
                minutes = timePicker.currentMinute
            }

            // Generate value to save
            val minutesAfterMidnight = hours * 60 + minutes

            // Save the value
            preference.apply {
                // This allows the client to ignore the user value.
                if (callchangelistener(minutesAfterMidnight)) {
                    // Save the value
                    time = minutesAfterMidnight
                }
            }
            preference.summary = "$hours:${if (minutes < 10) "0$minutes" else "$minutes"}"
        }
    }

    override fun getPreference(): TimePickerPreference {
        return super.getPreference() as? TimePickerPreference
            ?: error("Preference is not a TimePreference")
    }

    companion object {
        fun newInstance(key: String?) = TimePickerPreferenceDialog().apply {
            arguments = Bundle(1).apply {
                putString(ARG_KEY,key)
            }
        }
    }
}

非常感谢您

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。