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:
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.
3 Réponses :
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,
),
),
],
);
}
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,
),
))),
);
}
}
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)),
),
),