轮廓透明的按钮,在飘动中带有渐变边框

Ole*_*ndr 4 flutter flutter-layout

是否可以在飘动中创建带有渐变边框的轮廓(透明)按钮?我尝试在BorderSide样式中使用LinearGradient,但不允许这样做。

Ank*_*bey 20

你可以通过做一个简单的技巧来实现这一点

您必须定义两个容器。第一个具有渐变背景的外部容器和第二个具有白色背景的内部容器。并且作为内部容器的子项,您可以放置​​任何东西,例如TextFieldText、另一个按钮等。

final kInnerDecoration = BoxDecoration(
  color: Colors.white,
  border: Border.all(color: Colors.white),
  borderRadius: BorderRadius.circular(32),
);

final kGradientBoxDecoration = BoxDecoration(
  gradient: LinearGradient(colors: [Colors.black, Colors.redAccent]),
  border: Border.all(
    color: kHintColor,
  ),
  borderRadius: BorderRadius.circular(32),
);
Run Code Online (Sandbox Code Playgroud)

现在这是你的观点

  Container(
    child: Padding(
             padding: const EdgeInsets.all(2.0),
             child: Container(
                      child:Text("Button Title with your style"),
                      decoration: kInnerDecoration,
                    ),
           ),
    height: 66.0,
    decoration: kGradientBoxDecoration,
  ),
Run Code Online (Sandbox Code Playgroud)

完毕 在此处输入图片说明

  • @Oleksandr 如果按钮内出现任何图像将会很奇怪。当然,每个人都希望只看到按钮的文本,而不是按钮内的屏幕内容。你可能是对的。这个答案可能无法满足您的要求。我刚刚分享了我一直在努力的代码。是否使用此代码完全由您决定。感谢您分享您的想法。 (2认同)

Eug*_*ene 16

我花了大约两个小时:)

带有渐变的平面轮廓的按钮

如何使用:

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                UnicornOutlineButton(
                  strokeWidth: 2,
                  radius: 24,
                  gradient: LinearGradient(colors: [Colors.black, Colors.redAccent]),
                  child: Text('OMG', style: TextStyle(fontSize: 16)),
                  onPressed: () {},
                ),
                SizedBox(width: 0, height: 24),
                UnicornOutlineButton(
                  strokeWidth: 4,
                  radius: 16,
                  gradient: LinearGradient(
                    colors: [Colors.blue, Colors.yellow],
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                  ),
                  child: Text('Wow', style: TextStyle(fontSize: 16)),
                  onPressed: () {},
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

和类本身:

class UnicornOutlineButton extends StatelessWidget {
  final _GradientPainter _painter;
  final Widget _child;
  final VoidCallback _callback;
  final double _radius;

  UnicornOutlineButton({
    @required double strokeWidth,
    @required double radius,
    @required Gradient gradient,
    @required Widget child,
    @required VoidCallback onPressed,
  })  : this._painter = _GradientPainter(strokeWidth: strokeWidth, radius: radius, gradient: gradient),
        this._child = child,
        this._callback = onPressed,
        this._radius = radius;

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _painter,
      child: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: _callback,
        child: InkWell(
          borderRadius: BorderRadius.circular(_radius),
          onTap: _callback,
          child: Container(
            constraints: BoxConstraints(minWidth: 88, minHeight: 48),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                _child,
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _GradientPainter extends CustomPainter {
  final Paint _paint = Paint();
  final double radius;
  final double strokeWidth;
  final Gradient gradient;

  _GradientPainter({@required double strokeWidth, @required double radius, @required Gradient gradient})
      : this.strokeWidth = strokeWidth,
        this.radius = radius,
        this.gradient = gradient;

  @override
  void paint(Canvas canvas, Size size) {
    // create outer rectangle equals size
    Rect outerRect = Offset.zero & size;
    var outerRRect = RRect.fromRectAndRadius(outerRect, Radius.circular(radius));

    // create inner rectangle smaller by strokeWidth
    Rect innerRect = Rect.fromLTWH(strokeWidth, strokeWidth, size.width - strokeWidth * 2, size.height - strokeWidth * 2);
    var innerRRect = RRect.fromRectAndRadius(innerRect, Radius.circular(radius - strokeWidth));

    // apply gradient shader
    _paint.shader = gradient.createShader(outerRect);

    // create difference between outer and inner paths and draw it
    Path path1 = Path()..addRRect(outerRRect);
    Path path2 = Path()..addRRect(innerRRect);
    var path = Path.combine(PathOperation.difference, path1, path2);
    canvas.drawPath(path, _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this;
}
Run Code Online (Sandbox Code Playgroud)

  • 我已经发布了包 https://pub.dev/packages/outline_gradient_button 它仍然无法在网络上工作,因为创建着色器和路径操作目前不支持,将等待可能会发生一些变化 (2认同)

Cop*_*oad 6

使用OutlinedButton(推荐)

在此输入图像描述


创建此类(空安全代码)

class MyOutlinedButton extends StatelessWidget {
  final VoidCallback onPressed;
  final Widget child;
  final ButtonStyle? style;
  final Gradient? gradient;
  final double thickness;

  const MyOutlinedButton({
    Key? key,
    required this.onPressed,
    required this.child,
    this.style,
    this.gradient,
    this.thickness = 2,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: BoxDecoration(gradient: gradient),
      child: Container(
        color: Colors.white,
        margin: EdgeInsets.all(thickness),
        child: OutlinedButton(
          onPressed: onPressed,
          style: style,
          child: child,
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

MyOutlinedButton(
  onPressed: () {},
  gradient: LinearGradient(colors: [Colors.indigo, Colors.pink]),
  child: Text('OutlinedButton'),
)
Run Code Online (Sandbox Code Playgroud)