Set rounded color background to text in TextField Flutter

641

Solution 1

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

Solution 2

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

Solution 3

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

Solution 4

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

Solution 5

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

Share:
641
nicover
Author by

nicover

Updated on January 01, 2023

Comments

  • nicover
    nicover over 1 year

    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

  • Csisanyi
    Csisanyi over 2 years
    Try with specifying the keyboardType property
  • nicover
    nicover over 2 years
    Unfortunately it can't be done with this . Please see my screenshot
  • nicover
    nicover over 2 years
    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
    nicover over 2 years
    Thanks for answer. Please see edits
  • nicover
    nicover over 2 years
    Thanks for answer. Please see edits
  • nicover
    nicover over 2 years
    Thanks for answer. Please see edits
  • Csaba Mihaly
    Csaba Mihaly over 2 years
    It doesn't work on web with the html renderer