0

I need a container which has borders only on top, bottom and right side. In addition the bottomRight and topRight corners should be rounded.

Here is my code for some context:

Container(
  decoration: BoxDecoration(
    color: Colors.black.withOpacity(0.45),
    borderRadius: BorderRadius.only(
      bottomRight: Radius.circular(20),
      topRight: Radius.circular(20)),
    border: Border(
      top: BorderSide(
        color: Colors.white.withOpacity(0.45),
        width: 4.0),
      bottom: BorderSide(
        color: Colors.white.withOpacity(0.45),
        width: 4.0),
      right: BorderSide(
        color: Colors.white.withOpacity(0.45),
        width: 4.0),
    ),
    ...

With this code I produce the following error, which requires borderRadius to have uniform borders (which I do not want in this case).

Error to circumvent:

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during paint():
A borderRadius can only be given for a uniform Border.
Shaan Mephobic
  • 1,148
  • 2
  • 7
  • 15
Jahn E.
  • 1,228
  • 3
  • 6
  • 21

2 Answers2

0

I have 2 options:

1, You will need learn about create CustomPainter. You can customize your border by create a Paint and path.

2, Use two Container.

           Container(
                  height: 48,
                  width: 200,
                  padding: EdgeInsets.all(4).copyWith(left: 0),
                  decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.45),
                    borderRadius: BorderRadius.only(
                        bottomRight: Radius.circular(20),
                        topRight: Radius.circular(20)),
                  ),
                child: Container(
                  decoration: BoxDecoration(
                    color: Colors.black.withOpacity(0.45),
                    borderRadius: BorderRadius.only(
                        bottomRight: Radius.circular(20),
                        topRight: Radius.circular(20)),
                  ),
                ),
              ),
dangngocduc
  • 1,588
  • 8
  • 13
  • Thank you, however, your second solution does not achieve my desired effect. The fill color of the "outer" container, which replaces the border also distorts the black color with 45% opacity. I need a Colors.black.withOpacity(0.45) background and a Colors.white.withOpacity(0.45) border. – Jahn E. Oct 20 '21 at 08:47
0

I found a solution, which also works for transparent colors:

  1. Wrap the container with a Stack() and use another Container() to hide the left border. For the desired effect give both containers the same color and adjust the height (deduct 2x border width from the 1st Container to get the height of the 2nd Container).
  2. To position the "Border"-Container to the left add alignment: Alignment.centerLeft, to the stack.
  3. In order to show a text within this custom container, you need to position the Child-Widget (which you would directly add to the child parameter of the first container) as a separate widget to a Row() with your Child-Widget and the "Border"-Container as its children.
  4. To align the Child-Widget correctly, use the row´s mainAxisAlignment: MainAxisAlignment.spaceBetween, and wrap the Child-Widget with Padding() to ensure the "Border"-Container will stick to the left border.

Here is the code for the desired widget:

  Stack(
          alignment: Alignment.centerLeft,
          children: [
            Container(
              height: 493.0,
              width: 1353.0,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.white, width: 4.0),
                color: Colors.black.withOpacity(0.45),
                borderRadius: BorderRadius.only(
                  bottomRight: Radius.circular(20),
                  topRight: Radius.circular(20),
                ),
                boxShadow: [
                  CustomBoxShadow(
                    color: Colors.white,
                    blurRadius: 15.0,
                    blurStyle: BlurStyle.outer,
                  )
                ],
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                // Acts as the left border
                Container(
                  width: 4.0,
                  height: 485.0,
                  color: Colors.black,
                ),
                SizedBox(width: 115.0),
                Padding(
                  padding: const EdgeInsets.only(
                    right: 75.0,
                  ),
                  child: Text(
                    "Add the child widget here",
                    style: TextStyle(color: Colors.white),
                  ), // Add text here
                )
              ],
            )
          ],
        ),

For your information: If you want a BoxShadow, you run into the problem that it will change your transparent container color, as Flutter draws the shadow behind the widget. I added a CustomBoxShadow below, which allows to change the default blurStyle. Use blurStyle: BlurStyle.outer, to keep your desired transparent background color of the container. The code is from here: SO-Link.

class CustomBoxShadow extends BoxShadow {
  final BlurStyle blurStyle;

  const CustomBoxShadow({
    Color color = const Color(0xFF000000),
    Offset offset = Offset.zero,
    double blurRadius = 0.0,
    this.blurStyle = BlurStyle.normal,
  }) : super(color: color, offset: offset, blurRadius: blurRadius);

  @override
  Paint toPaint() {
    final Paint result = Paint()
      ..color = color
      ..maskFilter = MaskFilter.blur(this.blurStyle, blurSigma);
    assert(() {
      if (debugDisableShadows) result.maskFilter = null;
      return true;
    }());
    return result;
  }
}
Jahn E.
  • 1,228
  • 3
  • 6
  • 21