简体   繁体   English

如何创建带有圆角和渐变背景的 RaisedButton?

[英]How to create RaisedButton with rounded corner, and gradient background?

I have been trying to create a raised button with a rounded corner, and gradient background but to no success.我一直在尝试创建一个带有圆角和渐变背景的凸起按钮,但没有成功。 I can only implement one or the other.我只能实现其中一个。 It's been 2 hours and I haven't found a solution myself, on how I can implement both a rounded corner, and a gradient background together.已经 2 个小时了,我自己还没有找到解决方案,关于如何同时实现圆角和渐变背景。

Below are my codes of my latest attempt to implement a raised button with rounded corner, and gradient background.下面是我最近尝试实现带圆角和渐变背景的凸起按钮的代码。

Custom class of GradientButton GradientButton 的自定义类

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,
            )),
      ),
    );
  }
}

How I use the above code:我如何使用上面的代码:

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

How it looks like:它的样子:

在此处输入图片说明

As you can see, the gradient is there, but when I attempt to create a rounded corner, it overlaps, and the gradient is behind.如您所见,渐变就在那里,但是当我尝试创建圆角时,它重叠了,渐变就在后面。

There is a simple solution.有一个简单的解决方案。 Add the same border radius to both the button and the container inside the button.为按钮和按钮内的容器添加相同的边框半径。 Here is a simple example.这是一个简单的例子。

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)),
   ),
),

截屏

I suggest you put a Container with a gradient below the button in a Stack and cut its corners with ClipRRect while leaving the button's color transparent.我建议您在Stack中的按钮下方放置一个带有渐变的Container并使用ClipRRect同时保持按钮的颜色透明。 This way you keep touch feedback and pressed button shadow, as well as accessibility support.通过这种方式,您可以保持触摸反馈和按下按钮的阴影,以及辅助功能支持。

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,
            ),
          ),
        ],
      );
}

If anyone ever encounters the same issue.如果有人遇到同样的问题。 Here is my code on how I got it solved.这是我如何解决它的代码。

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,
                ),
              ))),
    );
  }
}

Use ElevatedButton (Recommended as of Flutter 2.0)使用ElevatedButton (从 Flutter 2.0 开始推荐)

在此处输入图片说明


@override
Widget build(BuildContext context) {
  final radius = BorderRadius.circular(20);
  return Scaffold(
    body: Center(
      child: DecoratedBox(
        decoration: BoxDecoration(
          gradient: LinearGradient(colors: [Colors.cyanAccent, Colors.red]),
          borderRadius: radius,
        ),
        child: ElevatedButton(
          onPressed: () {},
          child: Text('Elevated Button'),
          style: ElevatedButton.styleFrom(
            primary: Colors.transparent,
            shape: RoundedRectangleBorder(borderRadius: radius),
          ),
        ),
      ),
    ),
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM