inicializar - personalizar datepicker android studio
El widget DatePicker no ocupa todo AlertDialog en Nexus 6 (4)
Tengo un DatePickerFragment que usa un diseño personalizado muy simple. El diseño ocupa todo el diálogo de alerta en dispositivos más pequeños (HTC One m7), pero no en el Nexus 6. ¿Alguien sabe por qué el DatePicker no ocupa todo el ancho del Diálogo de alerta de Nexus 6 o dónde comenzar la resolución de problemas? ¡Gracias!
Nexus 6 (observe que el encabezado de fecha no llena el cuadro de diálogo de alerta completo)
HTC One m7
dialog_date.xml
<?xml version="1.0" encoding="utf-8"?>
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_date_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:calendarViewShown="false">
</DatePicker>
onCreateDialog () de DatePickerFragment
public Dialog onCreateDialog(Bundle savedInstanceState) {
Date date = (Date) getArguments().getSerializable(ARG_DATE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
View v = LayoutInflater.from(getActivity())
.inflate(R.layout.dialog_date, null);
mDatePicker = (DatePicker)
v.findViewById(R.id.dialog_date_date_picker);
mDatePicker.init(year, month, day, null);
return new AlertDialog.Builder(getActivity())
.setView(v)
// .setTitle(R.string.date_picker_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int year = mDatePicker.getYear();
int month = mDatePicker.getMonth();
int day = mDatePicker.getDayOfMonth();
Date date = new GregorianCalendar(year, month, day).getTime();
sendResult(Activity.RESULT_OK, date);
}
})
.create();
}
El cuadro de diálogo de alerta tiene algunas reglas estrictas (¿extraño?) Que rigen su tamaño. No estoy seguro de cómo resolverlo realmente, pero hay una solución alternativa: una vez que se muestra el cuadro de diálogo, puede forzar su ancho para que coincida con el ancho del selector de fecha. Esto lo resolvió para mí, espero que también funcione para usted:
public Dialog onCreateDialog(Bundle savedInstanceState) { ... final AlertDialog alertDialog = new AlertDialog.Builder(getActivity()) ... .create(); alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); final Window window = getDialog().getWindow(); lp.copyFrom(window.getAttributes()); final View picker = window.findViewById(R.id.dialog_date_date_picker); lp.width = picker.getWidth(); lp.height = picker.getHeight(); window.setAttributes(lp); } }); return alertDialog; }
El motivo es que AlertDialog ocupa más espacio que el DatePicker infantil.
Asegúrese de utilizar el tema de diálogo (por ejemplo, Theme.AppCompat.Light.Dialog
) sin el sufijo de .Alert
.
No pude hacer que esto funcionara usando la sugerencia de nitzanj, pero modifiqué cómo creé el DatePickerDialog y funciona como esperaba ahora. La fuente completa está abajo. La diferencia clave está en onCreateDialog.
public class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener{
public static final String EXTRA_DATE =
"com.amicly.acaringtext.date";
private static final String ARG_DATE = "date";
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Date date = (Date) getArguments().getSerializable(ARG_DATE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month, day);
}
public static DatePickerFragment newInstance(Date date) {
Bundle args = new Bundle();
args.putSerializable(ARG_DATE, date);
DatePickerFragment fragment = new DatePickerFragment();
fragment.setArguments(args);
return fragment;
}
private void sendResult(int resultCode, Date date) {
if (getTargetFragment() == null) {
return;
}
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE, date);
getTargetFragment().
onActivityResult(getTargetRequestCode(), resultCode, intent);
}
@Override
public void onDateSet(DatePicker datePicker, int year, int month, int day) {
Date date = new GregorianCalendar(year, month, day).getTime();
sendResult(Activity.RESULT_OK, date);
}
}
Si alguien está golpeando su cabeza contra la pared al respecto (sin duda fue después de seis horas de lidiar con esto), entonces esto probablemente funcione para usted.
En lugar de usar un AlertDialog con un DatePicker dentro, use un DatePickerDialog. No solo es mucho más fácil de configurar, sino que se muestra como se espera.
Ejemplo de uso:
DateTime dateTime = new DateTime();
new DatePickerDialog(
getActivity(),
R.style.DatePickerDialogCustom,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
dateTime = new DateTime(
year,
month + 1,
dayOfMonth,
dateTime.getHourOfDay(),
dateTime.getMinuteOfHour()
);
etDate.setText(dateFormatter.print(dateTime));
}
},
dateTime.getYear(),
dateTime.getMonthOfYear() - 1,
dateTime.getDayOfMonth()
).show();
Los meses se compensan con 1 porque DatePicker devuelve valores de mes entre 0 y 11.
Para el estilo, NO use un estilo de Diálogo de alerta. Esto es realmente lo que causa el problema original. Si no necesita un estilo personalizado, simplemente elimínelo del constructor (no use null). Si está utilizando un estilo personalizado, simplemente cree un nuevo estilo en su styles.xml:
<style name="DatePickerDialogCustom" parent="@style/Theme.AppCompat.Dialog">
<item name="android:colorBackground">@color/background</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:datePickerStyle">@style/DatePickerCustom</item>
</style>
<style name="DatePickerCustom" parent="@android:style/Widget.Material.DatePicker">
<item name="android:headerBackground">@color/colorAccent</item>
</style>
No sé si el mismo problema afecta a TimePickers, pero si lo hago, me imagino que una solución similar funcionará.