Tôi sử dụng DatePickerDialog
để nhắc người dùng cho sinh nhật của họ. Thật không may, tôi đã nhận được một số khiếu nại từ người dùng về hộp thoại Theo chủ đề vật chất khi dùng thử, vì vậy việc chuyển sang hộp thoại không phải là một tùy chọn cho tôi: Tôi phải tuân theo hộp thoại theo chủ đề Holo.
Nó chỉ ra rằng Android 7.0 vận chuyển với một lỗi: cố gắng sử dụng chủ đề Holo trên nền tảng này thay vì quay trở lại bằng cách sử dụng bị hỏng Chủ đề tài liệu cho DatePickerDialog
.Xem các báo cáo này hai lỗi:
tôi đã sử dụng một hình thức sửa đổi của this workaround by Jeff Lockhart tham chiếu trong những báo cáo lỗi:
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;
}
}
Điều này không là:
- Lấy tin
DatePicker mDatePicker
lĩnh vực thuộc thoại
- này Lấy tin
DatePickerDelegate mDelegate
lĩnh vực thuộc này thoại
- Kiểm tra xem các đại biểu chưa được một thể hiện của
DatePickerSpinnerDelegate
(loại đại biểu chúng ta muốn)
- Hủy bỏ tất cả quan điểm từ các
DatePicker
, vì họ là những widget lịch Chất liệu
- Tạo một thể hiện mới của
DatePickerSpinnerDelegate
, và gán nó vào mDelegate
lĩnh vực mDatePicker
này thoại
- Re-init ialize
mDatePicker
với thông tin lịch và một số params để làm cho nó thổi phồng spinners
Để sử dụng workaround này, tôi tạo ra một ContextThemeWrapper
xung quanh tôi Context
, cho phép tôi để thiết lập một chủ đề, trong trường hợp này 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)
);
Ghi chú:
- Điều này sử dụng phản ánh để truy cập các trường riêng tư. Nói chung, đây không phải là một cách tiếp cận mạnh mẽ và bạn không thể tin tưởng vào nó. Tôi đang giảm thiểu rủi ro ở đây bằng 1) hạn chế việc này thành một phiên bản SDK, v24; và 2) gói toàn bộ bit của mã phản chiếu trong một khối
try {...} catch (Exception e) {/* NOP */}
, vì vậy nếu bất kỳ sự phản ánh nào không thành công, thì sẽ không có gì xảy ra và dự phòng Vật liệu mặc định bị hỏng (sẽ bị hỏng) sẽ được sử dụng.
- Báo cáo lỗi ở trên cho biết rằng sự cố này đã được khắc phục trong Android 7.1 (SDK 25). Tôi chưa thử nghiệm điều này.
- original workaround code là dành cho
TimePickerDialog
gặp phải sự cố tương tự. Tôi đã sửa đổi nó để làm việc với DatePickerDialog
thay vào đó, và cũng đơn giản hóa các giải pháp được ít chung chung, và cụ thể hơn cho trường hợp sử dụng chính xác của tôi. Tuy nhiên, bạn có thể sử dụng phiên bản gốc hoàn chỉnh hơn và chỉ tinh chỉnh nó cho Date
thay vì Time
.
Bạn đã cập nhật thư viện hỗ trợ của mình chưa? – Shuddh
@Shuddh đã thử nhưng vẫn giống nhau :) Tôi đã thử '24 .2.1 'https://developer.android.com/topic/libraries/support-library/revisions.html –
Tôi cũng đang gặp sự cố này. Bất cứ ai có một giải pháp? – FinalFive