问题描述
我正在实现自定义TimePicker
,用于在PreferenceFragmentCompat
片段中设置首选项,主要遵循this指南。当我成功使之工作时,对话框的大小与另一个活动中相同对话框的大小并不相同。
对于TimePicker
,PreferenceFragmentCompat
中的一个看起来像这样
如果我将TimePicker
放在其他任何活动中,外观都是
对于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 (将#修改为@)