De la part de nos clients, nous souhaitons conserver le style HOLO sur le DatePickerDialog pour toutes les versions d’OS Android, comme par exemple: DatePicker sur Android 7 -
Mais cela ne semble pas fonctionner correctement sur Android 7:
Depuis ma mise en œuvre:
new DatePickerDialog(getContext(), AlertDialog.THEME_HOLO_LIGHT,
mCalendarPickerListener,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
Cela fonctionne bien pour les versions antérieures d'Android 7. Quelqu'un a le même problème?
Modifié: la solution est corrigée dans l'API 25 https://code.google.com/u/106133255289400340786/
J'utilise un DatePickerDialog
pour inviter les utilisateurs pour leurs anniversaires. Malheureusement, lors de l’essai, plusieurs utilisateurs se sont plaints du dialogue sur le thème Matériau. Je ne peux donc pas y basculer: je dois m'en tenir au dialogue sur le thème Holo.
Il s'avère que Android 7.0 est livré avec un bogue: essayer d'utiliser le thème Holo sur cette plate-forme revient plutôt à utiliser un thème matériel broken pour la DatePickerDialog
. Voir ces deux rapports de bugs:
J'ai utilisé une forme modifiée de cette solution de contournement de Jeff Lockhart référencée dans ces rapports de bogue:
private static final class FixedHoloDatePickerDialog extends DatePickerDialog {
private FixedHoloDatePickerDialog(Context context, OnDateSetListener callBack,
int year, int monthOfYear, int dayOfMonth) {
super(context, callBack, year, monthOfYear, dayOfMonth);
// Force spinners on Android 7.0 only (SDK 24).
// Note: I'm using a naked SDK value of 24 here, because I'm
// targeting SDK 23, and Build.VERSION_CODES.N is not available yet.
// But if you target SDK >= 24, you should have it.
if (Build.VERSION.SDK_INT == 24) {
try {
final Field field = this.findField(
DatePickerDialog.class,
DatePicker.class,
"mDatePicker"
);
final DatePicker datePicker = (DatePicker) field.get(this);
final Class<?> delegateClass = Class.forName(
"Android.widget.DatePicker$DatePickerDelegate"
);
final Field delegateField = this.findField(
DatePicker.class,
delegateClass,
"mDelegate"
);
final Object delegate = delegateField.get(datePicker);
final Class<?> spinnerDelegateClass = Class.forName(
"Android.widget.DatePickerSpinnerDelegate"
);
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(datePicker, null);
datePicker.removeAllViews();
final Constructor spinnerDelegateConstructor =
spinnerDelegateClass.getDeclaredConstructor(
DatePicker.class,
Context.class,
AttributeSet.class,
int.class,
int.class
);
spinnerDelegateConstructor.setAccessible(true);
final Object spinnerDelegate = spinnerDelegateConstructor.newInstance(
datePicker,
context,
null,
Android.R.attr.datePickerStyle,
0
);
delegateField.set(datePicker, spinnerDelegate);
datePicker.init(year, monthOfYear, dayOfMonth, this);
datePicker.setCalendarViewShown(false);
datePicker.setSpinnersShown(true);
}
} catch (Exception e) { /* Do nothing */ }
}
}
/**
* Find Field with expectedName in objectClass. If not found, find first occurrence of
* target fieldClass in objectClass.
*/
private Field findField(Class objectClass, Class fieldClass, String expectedName) {
try {
final Field field = objectClass.getDeclaredField(expectedName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) { /* Ignore */ }
// Search for it if it wasn't found under the expectedName.
for (final Field field : objectClass.getDeclaredFields()) {
if (field.getType() == fieldClass) {
field.setAccessible(true);
return field;
}
}
return null;
}
}
Ce que cela fait est:
DatePicker mDatePicker
appartenant à cette boîte de dialogueDatePickerDelegate mDelegate
appartenant à cette boîte de dialogueDatePickerSpinnerDelegate
(le type de délégué que nous voulons)DatePicker
, car ce sont les widgets de calendrier MatériauDatePickerSpinnerDelegate
et affectez-la au champ mDelegate
de mDatePicker
de cette boîte de dialogue.mDatePicker
avec les informations de calendrier et quelques paramètres pour le gonfler.Pour utiliser cette solution de contournement, je crée une ContextThemeWrapper
autour de ma Context
, ce qui me permet de définir un thème, dans ce cas Holo:
final Context themedContext = new ContextThemeWrapper(
this.getContext(),
Android.R.style.Theme_Holo_Light_Dialog
);
final DatePickerDialog dialog = new FixedHoloDatePickerDialog(
themedContext,
datePickerListener,
calender.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
Remarques:
try {...} catch (Exception e) {/* NOP */}
. Ainsi, en cas d'échec de la réflexion, rien ne se passera et la solution de secours par défaut (malheureusement cassée) sera utilisée.TimePickerDialog
qui présentait un problème similaire. Je l'ai modifiée pour fonctionner avec DatePickerDialog
à la place et j'ai également simplifié la solution pour qu'elle soit moins générique et plus spécifique à mon cas d'utilisation exact. Cependant, vous pouvez utiliser la version originale plus complète et le modifier pour Date
au lieu de Time
.Le sélecteur de date a son propre style https://developer.Android.com/reference/Android/R.style.html#Widget_DatePicker
Je pense que vous avez besoin de R.style.Widget.Holo.DatePicker
au lieu de AlertDialog.THEME_HOLO_LIGHT
. Il est possible que vous deviez créer votre propre style vide avec @Android:style/Widget.Holo.DatePicker
comme parent et l'utiliser.
Essayez de suivre cela fonctionne. J'ai testé. Et il n'y a pas de lacunes.
De plus, mDatePickerListener
est mon DatePickerListner que vous pouvez créer.
//Setting theme to Android.R.style.Theme_Holo_Light_Dialog
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
DatePickerDialog datePicker = new DatePickerDialog(getContext(), Android.R.style.Theme_Holo_Light_Dialog,
mDatePickerListener,
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH));
datePicker.setCancelable(false);
datePicker.setTitle(getString(R.string.select_your_dob));
//This line is important to remove blank gaps
datePicker.getWindow().setBackgroundDrawable(new ColorDrawable(Android.graphics.Color.TRANSPARENT));
datePicker.show();