94 votes

Flutter : Comment modifier la largeur d'un AlertDialog ?

Je me demande comment changer la largeur par défaut d'un AlertDialog, je n'ai réussi qu'à changer le rayon de la bordure :

Voici mon code :

showDialog(
       context: context,
       builder: (_) =>
            new AlertDialog(
               shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.all(Radius.circular(10.0))
               ),
               content: ProductPreviewScreen(),
            )
    );

Résultat attendu :

enter image description here Any idea?

7voto

Cirec Beback Points 478

Ma solution consiste à enfermer le dialogue dans un widget qui évite le remplissage supplémentaire ajouté par la classe Dialog en modifiant les MediaQueryData.

import 'package:myapp/widgets/dialog_inset_defeat.dart';
...

showDialog(
    context: context,
    builder: (_) => DialogInsetDefeat(
      context: context,
      child: SimpleDialog(...),
    )
);

... ou utilisez showDialogWithInsets() pour des valeurs personnalisées :

showDialogWithInsets(
    context: context,
    edgeInsets: EdgeInsets.symmetric(horizontal: 8),
    builder: (_) => SimpleDialog(...),
    )
);

Fichier dialog_inset_defeat.dart

   import 'package:flutter/material.dart';

/// A widget to defeat the hard coded insets of the [Dialog] class which
/// are [EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0)].
///
/// See also:
///
///  * [Dialog], for dialogs that have a message and some buttons.
///  * [showDialog], which actually displays the dialog and returns its result.
///  * <https://material.io/design/components/dialogs.html>
///  * <https://stackoverflow.com/questions/53913192/flutter-change-the-width-of-an-alertdialog>
class DialogInsetDefeat extends StatelessWidget {
  final BuildContext context;
  final Widget child;
  final deInset = EdgeInsets.symmetric(horizontal: -40, vertical: -24);
  final EdgeInsets edgeInsets;

  DialogInsetDefeat({@required this.context, @required this.child, this.edgeInsets});

  @override
  Widget build(BuildContext context) {
    var netEdgeInsets = deInset + (edgeInsets ?? EdgeInsets.zero);
    return MediaQuery(
      data: MediaQuery.of(context).copyWith(viewInsets: netEdgeInsets),
      child: child,
    );
  }
}

/// Displays a Material dialog using the above DialogInsetDefeat class.
/// Meant to be a drop-in replacement for showDialog().
///
/// See also:
///
///  * [Dialog], on which [SimpleDialog] and [AlertDialog] are based.
///  * [showDialog], which allows for customization of the dialog popup.
///  * <https://material.io/design/components/dialogs.html>
Future<T> showDialogWithInsets<T>({
  @required BuildContext context,
  bool barrierDismissible = true,
  @required WidgetBuilder builder,
  EdgeInsets edgeInsets,
}) {
  return showDialog(
    context: context,
    builder: (_) => DialogInsetDefeat(
      context: context,
      edgeInsets: edgeInsets,
      child: Builder(builder: builder),
    ),
    // Edited! barrierDismissible: barrierDismissible = true,
    barrierDismissible: barrierDismissible,
  );
}

Cela fonctionne pour moi à partir de Flutter 1.8.3. YMMV

0 votes

Notez qu'il s'agit en fait d'une astuce pour contourner les valeurs codées en dur dans la boîte à outils. Les versions ultérieures de Flutter permettront peut-être une plus grande flexibilité. Il s'efforce de travailler avec le cadre existant plutôt que de le remplacer, bien que chaque solution ait sa place.

0 votes

@Crec Beback Il ne peut pas se fermer en tapant hors du conteneur.

0 votes

@shinriyo Je n'ai pas testé depuis un moment. En revoyant mon code (à vue de nez seulement), je m'attendrais à l'erreur inverse où toujours "barrierDismissible". J'ai mis à jour ce qui précède.

6voto

ranjit joshi Points 51

Utiliser Dialog()

Dialog(
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
  insetPadding: EdgeInsets.all(15),
  child: SingleChildScrollView(
    child: Container(),
    ),
  ),
);

0 votes

Il est préférable de fournir quelques détails sur la réponse pour que la communauté SO puisse s'y référer ultérieurement.

6voto

Felipe Carvalho Points 11

J'ai enfin trouvé un moyen de modifier la largeur d'un AlertDialog. Il suffit d'entourer le "contenu" d'un conteneur et de lui attribuer une largeur.

return AlertDialog(
...
content: Container(
   width: MediaQuery.of(context).size.width*0.45,
   child: ...

AlertDialog avec largeur modifiée

1 votes

Toutes les autres solutions étaient plus compliquées ou utilisaient un autre Widget.

5voto

BRIJESH SAKARIYA Points 111

Vous pouvez modifier la propriété insetPadding de l'AlertDialog, ce sera un moyen simple pour vous.

 void alertBox() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        insetPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
        // (horizontal:10 = left:10, right:10)(vertical:10 = top:10, bottom:10)
        contentPadding: EdgeInsets.zero,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        content: Container(
          width: MediaQuery.of(context).size.width - 20,
          // width = device width minus insetPadding = deviceWidth - 20  (left:10, right:10 = 20)
          height: MediaQuery.of(context).size.height - 20,
          // height = device height minus insetPadding = deviceHeight - 20  (top:10, bottom:10 = 20)
          child: ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: Card(
              margin: EdgeInsets.zero,
              color: Colors.amber,
            ),
          ),
        ),
      ),
    );
  }

5voto

Yohan de Rose Points 54

L'utilisation de insetWidth et de future builder etc. n'a pas fonctionné pour moi - la simple modification de la largeur de l'élément de contenu a fonctionné parfaitement.

showDialog(
    context: context,
    builder: (context) {
      Future.delayed(Duration(seconds: 1000), () {
        Navigator.of(context).pop(true);
      });
      return AlertDialog(
        insetPadding: EdgeInsets.all(8.0),
        title: Text(
          "Time to go pro!",
          textAlign: TextAlign.center,
        ),
        content: Container(
          width: MediaQuery.of(context).size.width,
          child: BuySheet(
              applePayEnabled: applePayEnabled,
              googlePayEnabled: googlePayEnabled,
              applePayMerchantId: applePayMerchantId,
              squareLocationId: squareLocationId),
        ),
      );
    });

Result of the above code

1 votes

Excellent ! insetPadding + container's width crée un dialogue pleine largeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X