La réponse d'Olivierg a fonctionné pour moi et est la meilleure solution si la création d'une classe de dialogue personnalisée est l'itinéraire que vous souhaitez emprunter. Cependant, cela me dérangeait de ne pas pouvoir utiliser la classe AlertDialog. Je voulais pouvoir utiliser le style par défaut du système AlertDialog. La création d'une classe de boîte de dialogue personnalisée n'aurait pas ce style.
J'ai donc trouvé une solution (hack) qui fonctionnera sans avoir à créer une classe personnalisée, vous pouvez utiliser les constructeurs existants.
Le AlertDialog place une vue au-dessus de votre vue de contenu en tant qu'espace réservé pour le titre. Si vous trouvez la vue et définissez la hauteur sur 0, l'espace disparaît.
J'ai testé cela sur 2.3 et 3.0 jusqu'à présent, il est possible que cela ne fonctionne pas encore sur toutes les versions.
Voici deux méthodes d'assistance pour le faire:
/**
* 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;
}
Voici un exemple de la façon dont il est utilisé:
Dialog dialog = new AlertDialog.Builder(this)
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, true);
Si vous l'utilisez avec un DialogFragment, remplacez la onCreateDialog
méthode de DialogFragment . Ensuite, créez et renvoyez votre boîte de dialogue comme le premier exemple ci-dessus. Le seul changement est que vous devez passer false comme 3e paramètre (show) pour qu'il n'appelle pas show () dans la boîte de dialogue. DialogFragment s'en occupera plus tard.
Exemple:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new AlertDialog.Builder(getContext())
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, false);
return dialog;
}
Au fur et à mesure que je testerai cela, je serai sûr de mettre à jour avec tous les réglages supplémentaires nécessaires.