Odpowiedź olivierga zadziałała dla mnie i jest najlepszym rozwiązaniem, jeśli utworzenie niestandardowej klasy Dialog to trasa, którą chcesz się udać. Niepokoiło mnie jednak, że nie mogę użyć klasy AlertDialog. Chciałem móc korzystać z domyślnego systemu AlertDialog. Utworzenie niestandardowej klasy okna dialogowego nie miałoby tego stylu.
Więc znalazłem rozwiązanie (hack), które będzie działać bez konieczności tworzenia niestandardowej klasy, możesz użyć istniejących konstruktorów.
AlertDialog umieszcza widok nad widokiem zawartości jako symbol zastępczy tytułu. Jeśli znajdziesz widok i ustawisz wysokość na 0, przestrzeń zniknie.
Do tej pory przetestowałem to na 2.3 i 3.0, możliwe, że nie działa jeszcze w każdej wersji.
Oto dwie metody pomocnicze:
/**
* 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;
}
Oto przykład jego użycia:
Dialog dialog = new AlertDialog.Builder(this)
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, true);
Jeśli używasz tego z DialogFragment, zastąp onCreateDialog
metodę DialogFragment . Następnie utwórz i zwróć okno dialogowe jak w pierwszym przykładzie powyżej. Jedyną zmianą jest to, że powinieneś przekazać false jako trzeci parametr (show), aby nie wywoływał show () w oknie dialogowym. DialogFragment zajmie się tym później.
Przykład:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new AlertDialog.Builder(getContext())
.setView(yourCustomView)
.create();
showDialogWithNoTopSpace(yourCustomView, dialog, false);
return dialog;
}
Gdy będę to testować dalej, będę musiał zaktualizować o wszelkie dodatkowe poprawki.