La respuesta de olivierg funcionó para mí y es la mejor solución si crear una clase de Diálogo personalizada es la ruta que desea seguir. Sin embargo, me molestó que no pudiera usar la clase AlertDialog. Quería poder usar el estilo predeterminado del sistema AlertDialog. Crear una clase de diálogo personalizada no tendría este estilo.
Así que encontré una solución (hack) que funcionará sin tener que crear una clase personalizada, puede usar los constructores existentes.
AlertDialog coloca una Vista sobre su vista de contenido como un marcador de posición para el título. Si encuentra la vista y establece la altura en 0, el espacio desaparece.
He probado esto en 2.3 y 3.0 hasta ahora, es posible que todavía no funcione en todas las versiones.
Aquí hay dos métodos de ayuda para hacerlo:
/**
* Show a Dialog with the extra title/top padding collapsed.
*
* @param customView The custom view that you added to the dialog
* @param dialog The dialog to display without top spacing
* @param show Whether or not to call dialog.show() at the end.
*/
public static void showDialogWithNoTopSpace(final View customView, final Dialog dialog, boolean show) {
// Now we setup a listener to detect as soon as the dialog has shown.
customView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Check if your view has been laid out yet
if (customView.getHeight() > 0) {
// If it has been, we will search the view hierarchy for the view that is responsible for the extra space.
LinearLayout dialogLayout = findDialogLinearLayout(customView);
if (dialogLayout == null) {
// Could find it. Unexpected.
} else {
// Found it, now remove the height of the title area
View child = dialogLayout.getChildAt(0);
if (child != customView) {
// remove height
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
lp.height = 0;
child.setLayoutParams(lp);
} else {
// Could find it. Unexpected.
}
}
// Done with the listener
customView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
// Show the dialog
if (show)
dialog.show();
}
/**
* Searches parents for a LinearLayout
*
* @param view to search the search from
* @return the first parent view that is a LinearLayout or null if none was found
*/
public static LinearLayout findDialogLinearLayout(View view) {
ViewParent parent = (ViewParent) view.getParent();
if (parent != null) {
if (parent instanceof LinearLayout) {
// Found it
return (LinearLayout) parent;
} else if (parent instanceof View) {
// Keep looking
return findDialogLinearLayout((View) parent);
}
}
// Couldn't find it
return null;
}
Aquí hay un ejemplo de cómo se usa:
Dialog dialog = new AlertDialog.Builder(this)
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, true);
Si está utilizando esto con un DialogFragment, anule el onCreateDialog
método del DialogFragment . Luego cree y devuelva su diálogo como el primer ejemplo anterior. El único cambio es que debe pasar falso como el tercer parámetro (show) para que no llame a show () en el cuadro de diálogo. El DialogFragment se encargará de eso más tarde.
Ejemplo:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new AlertDialog.Builder(getContext())
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, false);
return dialog;
}
A medida que lo pruebe más, me aseguraré de actualizar con cualquier ajuste adicional necesario.