2
votes

Comment créer RaisedButton avec un coin arrondi et un fond dégradé?

J'ai essayé de créer un bouton en relief avec un coin arrondi et un arrière-plan dégradé, mais sans succès. Je ne peux mettre en œuvre que l'un ou l'autre. Cela fait 2 heures et je n'ai pas trouvé de solution moi-même, sur la façon dont je peux implémenter à la fois un coin arrondi et un arrière-plan dégradé ensemble.

Voici mes codes de ma dernière tentative d'implémentation d'un bouton en relief avec un coin arrondi, et fond dégradé.

Classe personnalisée de GradientButton

RaisedGradientButton(
    onPressed: navigateToNextPage,
        child: Text("Select Community"),
)

Comment j'utilise le code ci-dessus:

class RaisedGradientButton extends StatelessWidget {
  final Widget child;
  final Gradient gradient;
  final double width;
  final double height;
  final Function onPressed;

  const RaisedGradientButton({
    Key key,
    @required this.child,
    this.gradient,
    this.width = double.infinity,
    this.height = 50.0,
    this.onPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: 50.0,
      decoration: BoxDecoration(
        gradient: new LinearGradient(
          colors: [
            Colors.blue,
            Colors.red,
          ],
          begin: FractionalOffset.centerLeft,
          end: FractionalOffset.centerRight,
        ),
      ),
      child: Material(
        shape: new RoundedRectangleBorder(
            borderRadius: new BorderRadius.circular(128.0)),
//        color: Colors.transparent,
        child: InkWell(
            onTap: onPressed,
            child: Center(
              child: child,
            )),
      ),
    );
  }
}

À quoi ça ressemble:

 entrez la description de l'image ici

Comme vous pouvez le voir, le dégradé est là, mais quand j'essaye de créer un coin arrondi, il se chevauche et le dégradé est derrière.


0 commentaires

3 Réponses :


2
votes

Je vous suggère de mettre un Container avec un dégradé sous le bouton dans une Stack et de couper ses coins avec ClipRRect en laissant la couleur du bouton transparent. De cette façon, vous conservez les commentaires tactiles et l'ombre des boutons enfoncés, ainsi que la prise en charge de l'accessibilité.

class RaisedGradientButton extends StatelessWidget {
  final Widget child;
  final Gradient gradient;
  final double width;
  final double height;
  final Function onPressed;
  final borderRadius = BorderRadius.circular(128.0);

  RaisedGradientButton({
    Key key,
    @required this.child,
    Gradient gradient,
    this.width = double.infinity,
    this.height = 50.0,
    this.onPressed,
  })  : this.gradient = gradient ??
            LinearGradient(
              colors: [
                Colors.blue,
                Colors.red,
              ],
              begin: FractionalOffset.centerLeft,
              end: FractionalOffset.centerRight,
            ),
        super(key: key);

  @override
  Widget build(BuildContext context) => Stack(
        children: [
          Positioned.fill(
            child: ClipRRect(
              borderRadius: borderRadius,
              child: Container(
                width: width,
                height: height,
                decoration: BoxDecoration(
                  gradient: gradient,
                ),
              ),
            ),
          ),
          Container(
            width: width,
            height: height,
            child: RaisedButton(
              shape: RoundedRectangleBorder(
                borderRadius: borderRadius,
              ),
              padding: EdgeInsets.zero,
              child: Center(child: child),
              onPressed: onPressed,
              color: Colors.transparent,
            ),
          ),
        ],
      );
}


0 commentaires

0
votes

Si quelqu'un rencontre un jour le même problème. Voici mon code expliquant comment je l'ai résolu.

class GradientButton extends StatelessWidget {
  final Widget child;

  // final Gradient gradient;
  final double width;
  final double height;
  final bool isEnabled;
  final Function onPressed;

  const GradientButton({
    Key key,
    @required this.child,
    // this.gradient,
    this.isEnabled,
    this.width,
    this.height,
    this.onPressed,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Color _statusColor;
    if (isEnabled != null) {
      // Show gradient color by making material widget transparent
      if (isEnabled == true) {
        _statusColor = Colors.transparent;
      } else {
        // Show grey color if isEnabled is false
        _statusColor = Colors.grey;
      }
    } else {
      // Show grey color if isEnabled is null
      _statusColor = Colors.transparent;
    }

    return Container(
      width: width,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(8),
        gradient: LinearGradient(
          colors: [
            Color(0xFF3186E3),
            Color(0xFF1D36C4),
          ],
          begin: FractionalOffset.centerLeft,
          end: FractionalOffset.centerRight,
        ),
      ),
      child: Material(
          shape: RoundedRectangleBorder(
              borderRadius: new BorderRadius.circular(4)),
          color: _statusColor,
          child: InkWell(
              borderRadius: BorderRadius.circular(32),
              onTap: onPressed,
              child: Padding(
                padding: EdgeInsets.fromLTRB(24, 16, 24, 16),
                child: Center(
                  child: child,
                ),
              ))),
    );
  }
}


0 commentaires

3
votes

Il existe une solution simple. Ajoutez le même rayon de bordure au bouton et au conteneur à l'intérieur du bouton. Voici un exemple simple.

RaisedButton(
   onPressed: () {},
   textColor: Colors.white,
   color: Colors.transparent,
   padding: EdgeInsets.all(0),
   shape: RoundedRectangleBorder(
      borderRadius: new BorderRadius.circular(18.0),
   ),
   child: Container(
      decoration: BoxDecoration(
         borderRadius: BorderRadius.circular(18),
         gradient: LinearGradient(
            colors: <Color>[
               Colors.black38,
               Colors.black26,
               Colors.white38,
            ],
         ),
      ),
      padding: const EdgeInsets.fromLTRB(24, 12, 24, 12),
      child: const Text('Sign In', style: TextStyle(fontSize: 20)),
   ),
),

 screenshot


0 commentaires