【问题标题】:Flutter | How to draw custom borders around a widget / inside a Container颤振 |如何在小部件周围/容器内绘制自定义边框
【发布时间】:2020-01-01 08:51:33
【问题描述】:

我正在尝试实现一个外观类似于此图像中的 Flutter UI;

目前我正在尝试实现边框,基本上是一个顶部和底部切掉的边框,甚至可能切掉顶部,底部和两侧,只有角落。

我尝试了各种CustomPaint 方法,但它们都非常复杂,必须针对每个小部件完成。我觉得这应该很简单,但我找不到方法。

如何创建一个小部件来包装任何给定的小部件,例如 FlatButtonCardTextSpan,然后在其子项周围创建此边框?

或者更好的是,是否可以为整个应用程序/屏幕创建一个包装小部件,在特定小部件周围放置自定义边框?因此,如果小部件树包含任何FlatButton,他们将拥有CustomBorder,但说所有Text 不会?

【问题讨论】:

  • 分享你到目前为止的尝试
  • @shb 我很欣赏你这篇评论的目标,但我已经尝试了 3 天来使用我没有历史的方法和技术的混搭,并且没有一个接近我需要什么,所以尝试分享我迄今为止尝试过的东西基本上是毫无意义的。但我确实说过我曾尝试在我的技术中使用CustomPaint,但对于这样一个简单的任务来说,它是非常复杂的代码,而且它并没有实现外观。
  • @pskink 感谢您的输入,但我不可能仅基于装饰 api 类的链接开始实现这一目标。感谢您为我指出正确的方向,但也许您可以更近地指出我?我对 Dart/Flutter 还很陌生。
  • 谢谢,我尝试使用UnderlineTabIndicator 作为基础,然后扩展四个边,但我仍然无法做到,我设法使下划线更短,并尝试添加一点边界到右侧,但我不知道我在做什么......这就是我问这个问题的原因......也许你可以帮忙回答一下?
  • 好的,谢谢,我会试一试

标签: user-interface flutter dart


【解决方案1】:

自定义边框类

class TechBorder extends StatelessWidget {
  final Widget child;
  final Color borderColor;
  final double borderWidth, leftBorderLength, rightBorderLength;

  //This is just a sample, modify it as your requirement
  //add extra properties like padding,color etc.

  TechBorder(
      {Key k,
      @required this.child,
      @required this.borderColor,
      @required this.borderWidth,
      @required this.leftBorderLength,
      @required this.rightBorderLength,})
      : super(key: k);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          decoration: BoxDecoration(
                  border: Border(
                      left: BorderSide(color: borderColor, width: borderWidth),
                      right:
                          BorderSide(color: borderColor, width: borderWidth)),
                  color: Colors.transparent),
        ),
        Container(
            color: Colors.transparent,
            child: Stack(children: [
              Positioned(
                  top: 0,
                  left: 0,
                  child: Container(
                      color: borderColor,
                      width: leftBorderLength,
                      height: borderWidth)),
              Positioned(
                  bottom: 0,
                  left: 0,
                  child: Container(
                      color: borderColor,
                      width: leftBorderLength,
                      height: borderWidth)),
              Positioned(
                  right: 0,
                  child: Container(
                      color: borderColor,
                      width: rightBorderLength,
                      height: borderWidth)),
              Positioned(
                  bottom: 0,
                  right: 0,
                  child: Container(
                      color: borderColor,
                      width: rightBorderLength,
                      height: borderWidth)),
            ])),
        Padding(
          padding: const EdgeInsets.all(10.0),
          child: child,
        )
      ],
    );
  }
}

用法

Container(
            decoration: BoxDecoration(
                image: DecorationImage(
                    image: NetworkImage(
                      'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX18042265.jpg',
                    ),
                    fit: BoxFit.fill)),
            padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
            child: TechBorder(
              borderWidth:3.0,
              leftBorderLength:25,
              rightBorderLength:25,
                borderColor: Colors.blueAccent,
                child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Padding(
                          padding: EdgeInsets.only(top: 5, bottom: 5),
                          child: Text('SCREEN:  Ox1b o1197hgk500',
                              style: TextStyle(
                                  color: Colors.blueAccent, fontSize: 17))),
                      Padding(
                          padding: EdgeInsets.only(top: 5, bottom: 5),
                          child: Row(
                            children: <Widget>[
                              Text('3518',
                                  style: TextStyle(
                                      color: Colors.blueAccent, fontSize: 17)),
                              Container(
                                  margin: EdgeInsets.only(left: 15),
                                  color: Colors.blueAccent,
                                  height: 12,
                                  width: 80),
                              SizedBox(width: 8),
                              Container(
                                  color: Colors.blueAccent,
                                  height: 12,
                                  width: 100)
                            ],
                          )),
                      Padding(
                          padding: EdgeInsets.only(top: 5, bottom: 5),
                          child: Text('Other fields gos here...',
                              style: TextStyle(
                                  color: Colors.blueAccent, fontSize: 17))),
                    ])))

【讨论】:

  • 嘿,哇,谢谢,我现在就试试这个并进行一些调整以适应,但这正是我所需要的,我昨天花了几个小时被一个试图“教”我而不是实际上为我提供了一些示例代码来使用,所以感谢它的赞赏
猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 2020-10-13
  • 2014-11-06
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多