How to format FormBuilderRate (Flutter Form Builder package)?

541 Views Asked by At

I'm trying to format the appearance of FormBuilderRate within the flutter_form_builder package (link to package on pub.dev).

Specifically,

  1. How to eliminate or change the format of horizontal lines between items
  2. How to vertically align prefix Text (e.g., "Wwww..." in the screenshot below) with bottom or center of rating stars
  3. How to align right side of all four instances of prefix Text AND the left side of the rating stars, with a tighter gap between the prefix Text and left-most star (right now I'm using a hackey padding: const EdgeInsets.only approach)

screenshot of FormBuilderRate

Here's the code:

                    RichText(
                  text: TextSpan(
                    style: TextStyle(
                      color: Colors.blue,
                    ),
                    children: <TextSpan>[
                      TextSpan(
                        text:
                            '[ 7 ​]  On a 1 - 5 star scale, with 5 being the best, how would you rate each of the following: ', // clipped " for this house"
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 16.0,
                        ),
                      ),
                      TextSpan(
                        text:
                            '  (optional)', // put 2 spaces instead of "\n (line break)
                        style: TextStyle(
                          fontWeight: FontWeight.normal,
                          fontStyle: FontStyle.italic,
                          fontSize: 14.0,
                          color: Colors.black54,
                        ), // was 'misleading or inaccurate?',
                      ),
                    ],
                  ),
                ),
                SizedBox(
                  height: 6.0,
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 1.0),
                  child: FormBuilderRate(
                    attribute: 'zzz',
                    decoration: const InputDecoration(
                      // labelText: 'FormBuilderRate',
                      prefix: Text(
                        'Wwwwwwwwww',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 67.0),
                  child: FormBuilderRate(
                    attribute: 'zzz',
                    decoration: const InputDecoration(
                      //labelText: 'FormBuilderRate - kitchen:',
                      floatingLabelBehavior: FloatingLabelBehavior.auto,
                      prefix: Text(
                        'Xxxxxxx',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 30.0),
                  child: FormBuilderRate(
                    attribute: 'zzz',
                    decoration: const InputDecoration(
                      //labelText: 'FormBuilderRate - kitchen:',
                      floatingLabelBehavior: FloatingLabelBehavior.auto,
                      prefix: Text(
                        'Yyyyyyyyyyyy',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 56.0),
                  child: FormBuilderRate(
                    attribute: 'zzz',
                    decoration: const InputDecoration(
                      //labelText: 'FormBuilderRate - kitchen:',
                      floatingLabelBehavior: FloatingLabelBehavior.auto,
                      prefix: Text(
                        'Zzzzzzzz',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),

UPDATE #1 with partial answer:

@Miller's answer below using InputDecoration(border: InputBorder.none), removes the lines, but does not fix the problem of aligning prefix Text and stars.

Even so, here's the partial solution code:

Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Flexible(
                      flex: 1,
                      child: FormBuilderRate(
                        attribute: 'www',
                        decoration: const InputDecoration(
                          border: InputBorder.none,
                          prefix: Text(
                            'Row+Flexible Wwww',
                            style: TextStyle(
                              fontSize: 16,
                            ),
                            textAlign: TextAlign.end,
                          ),
                        ),
                        initialValue: 0,
                        filledColor:
                            Color(0xffFFB900), // later: use starIconColor
                        emptyIcon: Icons.star_border_outlined,
                        emptyColor:
                            Color(0xffFFB900), // later: use starIconColor
                        isHalfAllowed: true,
                        halfFilledIcon: Icons.star_half,
                        halfFilledColor:
                            Color(0xffFFB900), // later: use starIconColor
                        iconSize: 32.0,
                      ),
                    ),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Flexible(
                      flex: 1,
                      child: FormBuilderRate(
                        attribute: 'Xxxx',
                        decoration: const InputDecoration(
                          border: InputBorder.none,
                          prefix: Text(
                            'Row+Flexible',
                            style: TextStyle(
                              fontSize: 16,
                            ),
                            textAlign: TextAlign.end,
                          ),
                        ),
                        initialValue: 0,
                        filledColor:
                            Color(0xffFFB900), // later: use starIconColor
                        emptyIcon: Icons.star_border_outlined,
                        emptyColor:
                            Color(0xffFFB900), // later: use starIconColor
                        isHalfAllowed: true,
                        halfFilledIcon: Icons.star_half,
                        halfFilledColor:
                            Color(0xffFFB900), // later: use starIconColor
                        iconSize: 32.0,
                      ),
                    ),
                  ],
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 30.0),
                  child: FormBuilderRate(
                    attribute: 'yyy',
                    decoration: const InputDecoration(
                      border: InputBorder.none,
                      prefix: Text(
                        'Yyyyyyyyyyyy',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 56.0),
                  child: FormBuilderRate(
                    attribute: 'zzz',
                    decoration: const InputDecoration(
                      border: InputBorder.none,
                      prefix: Text(
                        'ZzzzzzzZ',
                        style: TextStyle(
                          fontSize: 16,
                        ),
                      ),
                    ),
                    initialValue: 0,
                    filledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    emptyIcon: Icons.star_border_outlined,
                    emptyColor:
                        Color(0xffFFB900), // later: use starIconColor
                    isHalfAllowed: true,
                    halfFilledIcon: Icons.star_half,
                    halfFilledColor:
                        Color(0xffFFB900), // later: use starIconColor
                    iconSize: 32.0,
                  ),
                ),

And here's what this looks like in the Android emulator (first two rating rows use @Miller's approach, which does not fix the #2 prefix vertical text alignment problem):

first two rating rows do not align to the end (right)

UPDATE #2: solved issue of vertically aligning prefix Text with rating stars:

Based on part of @Joe Muller's answer here, I made the actual text transparent, added a shadow, then positioned the shadow higher than the original text.

Here's that part of the code:

style: TextStyle(
                          fontSize: 16,
                          **color: Colors.transparent,
                          shadows: [
                            Shadow(
                                color: Colors.black54,
                                offset: Offset(0, -7))
                          ],**
                        ),

And here's a screenshot with the changes:

screenshot showing update #2 is effective

What's left is #3 from my original question: How to align right side of all four instances of prefix Text AND the left side of the rating stars, with a tighter gap between the prefix Text and left-most star (right now I'm using a hackey padding: const EdgeInsets.only approach)

1

There are 1 best solutions below

2
On
  1. To make changes to a field's underline, you could make use of the border attribute of InputDecoration. For example, to remove the whole underline: border: InputBorder.none,

  2. & 3. Kindly note that FormFields, like many other widgets, tend to take all the available width of their parent widget. I would therefore advise using a row between the Text and FormBuilderRate so as to have better control of the positioning of your widgets; like so:

Row(
  mainAxisAlignment: MainAxisAlignment.end,
  children: [
    Flexible(
      flex: 1,
      child: Text(
        'Wwwwwwwwww',
        style: TextStyle(fontSize: 16),
        textAlign: TextAlign.end,
      ),
    ),
    Flexible(
      flex: 1,
      child: FormBuilderRate(
        attribute: 'zzz',
        decoration: const InputDecoration(
          border: InputBorder.none
        ),
        initialValue: 0,
        filledColor: Color(0xffFFB900),
        emptyIcon: Icons.star_border_outlined,
        emptyColor: Color(0xffFFB900),
        isHalfAllowed: true,
        halfFilledIcon: Icons.star_half,
        halfFilledColor: Color(0xffFFB900),
        iconSize: 32.0,
      ),
    ),
  ],
),