7

I would like my text background in Textfield looks like this :

enter image description here

But with this code :

     style: TextStyle(
              background: Paint()..color = Colors.blue
                ..style = PaintingStyle.fill,
              color: Colors.white,
            ),

I have this result :

enter image description here

There is no padding, no rounded corners and a transparent line between both...

How can I do this ?

EDIT :

Another way with TextStyle was provided by @Csaba Mihaly but this is a workaround I want to avoid. I'm looking for a custom paint solution

EDIT :

According answers provided PaintStyle.stroke can be used but it's not 100% matching the expected result (first screen) :

No matter the text size is, in order to fill the empty space the stroke width must be bigger as I can see. It will render a large padding and corner radius. In my case :

enter image description here enter image description here

nicover
  • 2,213
  • 10
  • 24
  • Doesn't qualify as an answer but a definite improvement: https://dartpad.dev/?258cf448c698d3e9888d6a7bb0862839&null_safety=true I believe the solution would involve CustomPainter because of the merging effect of the bubbles. – happy-san Sep 23 '21 at 23:49
  • @happy_san could you provide an answer ? – nicover Sep 24 '21 at 00:02
  • 1
    I'll post if I get an answer. – happy-san Sep 24 '21 at 00:07
  • Someone already asked for this before https://stackoverflow.com/questions/64354364/how-to-make-custon-editable-textbox-on-a-canvas-in-flutter-in-which-background-s – Mohammed Alfateh Dec 08 '21 at 12:29
  • Do you want to modify your provided TextStyle to drive to your or want to try a different approach to get same result? – Diwyansh Dec 08 '21 at 14:10
  • @Diwyansh try a different approach is ok but I think the best solution is to create a custom paint with the TextStyle. just don't know how. Answers below use PaintStyle stroke as I found but it's not working with a large text fontsize because it will be transparent inside. The more the fontsize is bigger the more the stroke width should be. And then it will be not the same result (too large rounded corner and padding) – nicover Dec 08 '21 at 14:36

7 Answers7

7

You code snippet will work if you add ..strokeWidth = 20 to the style, e.g.:

Text(
    'Lorem Ipsum is simply dummy text of the printing and typesetting industry. ',
    textAlign: TextAlign.center,
    style: TextStyle(
     background: Paint()
       ..color = Colors.blue
       ..strokeWidth = 20
       ..strokeJoin = StrokeJoin.round
       ..strokeCap = StrokeCap.round
       ..style = PaintingStyle.stroke,
     color: Colors.white,
    ))

enter image description here

Stroke width defines the 'fatness' of the area around the text. Though to be accurate, the inside corners (look near word 'industry') are not rounded, I doubt text background can fix that.

Also please not that if you're targeting Web you might need to use Skia renderer instead of HTML renderer(https://stackoverflow.com/a/69975665/440696) in order to avoid the following artefact: enter image description here

Maxim Saplin
  • 4,115
  • 38
  • 29
4

I created a package called rounded_background_text to achive this

https://pub.dev/packages/rounded_background_text

Showcase

Usage:

import 'package:rounded_background_text/rounded_background_text.dart';

RoundedBackgroundText(
  'A cool text to be highlighted',
  style: const TextStyle(fontWeight: FontWeight.bold),
  backgroundColor: Colors.white,
),

TextFields are also supported

Bruno D'Luka
  • 63
  • 2
  • 5
3

Just give the desired strokeWidth value and it will work fine. Output Image

style: TextStyle(
        background: Paint()
          ..strokeWidth = 17
          ..color = Colors.blue
          ..strokeJoin = StrokeJoin.round
          ..strokeCap = StrokeCap.round
          ..style = PaintingStyle.stroke,

        color: Colors.black,
      )
Aman Ansari
  • 121
  • 1
  • 5
2

So I found this article https://medium.com/@pinkesh.earth/flutter-quick-tip-how-to-set-text-background-color-with-curve-d40a2f96a415 It describes how to use textstyle to look like what you want, but it doesn't exactly work like that, I don't know why. It draws the next line's background above the previous.

I managed to work around it (bug?) by stacking two textfields(one has transparent text, the other transparent background).

The result:

enter image description here

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final myControllerName = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData(
            inputDecorationTheme: const InputDecorationTheme(
          fillColor: Colors.transparent,
          filled: true,
          focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(color: Colors.transparent)),
          enabledBorder: UnderlineInputBorder(
            borderSide: BorderSide(color: Colors.transparent),
          ),
          border: UnderlineInputBorder(
            borderSide: BorderSide(color: Colors.transparent),
          ),
        )),
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            body: Center(
                child: Stack(
          children: [
            IntrinsicWidth(
              child: TextField(
                controller: myControllerName,
                style: TextStyle(
                    color: Colors.transparent,
                    fontWeight: FontWeight.w600,
                    fontSize: 20,
                    background: Paint()
                      ..strokeWidth = 25
                      ..color = Colors.blue
                      ..style = PaintingStyle.stroke
                      ..strokeJoin = StrokeJoin.round),
                keyboardType: TextInputType.multiline,
                maxLines: null,
                textAlign: TextAlign.center,
              ),
            ),
            IntrinsicWidth(
              child: TextField(
                controller: myControllerName,
                style: const TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.w600,
                    fontSize: 20,
                    backgroundColor: Colors.transparent),
                keyboardType: TextInputType.multiline,
                maxLines: null,
                textAlign: TextAlign.center,
              ),
            )
          ],
        ))));
  }
}
Csaba Mihaly
  • 149
  • 10
  • Thanks for your answer . this is exactly what I found days ago before I put the bounty. and I wrapped the first textfield by AbsorbPointer to avoid conflicts. I am sorry I can't accept this workaround because I'm looking for a custom paint solution . I'm going to edit my question according your solution . – nicover Dec 07 '21 at 13:45
2

Do like this:

style: TextStyle(
              background: Paint()..color = Colors.blue
                ..strokeJoin = StrokeJoin.round
                ..strokeCap = StrokeCap.round
                ..style = PaintingStyle.stroke
                ..strokeWidth = 30.0,
              color: Colors.white,
            ),
1

You can use a container. Try this:

Container(
  padding: EdgeInsets.all(10),
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(20),
    color: Colors.blue,
  ),
  child: Text(
    'Hello World!',
    style: TextStyle(
      color: Colors.white,
      fontSize: 20,
    ),
  ),
);
tripleee
  • 175,061
  • 34
  • 275
  • 318
max
  • 21
  • 4
0

Try something like this

TextField(
  keyboardType: TextInputType.multiline
  decoration: InputDecoration(
      border: OutlineInputBorder(
        borderRadius: BorderRadius.all(<value>),
      ),

You can find other examples here https://stacksecrets.com/flutter/flutter-textfield-decoration-in-depth#How_To_Decorate_Border_Of_TextField

Csisanyi
  • 669
  • 4
  • 16