3

How do you make a button in Flutter with transparant text so that the background picture can be seen through the text? I tried it with a raised button and then putting a opacity widget around the text widget but that just shows the background color of the button. When i searched for relevant questions i could only find this android question: Android button with transparent text

Example: https://i.stack.imgur.com/3W4u3.png

1 Answers1

4

You can use a ShaderMask with blendMode: BlendMode.srcOut. The ClipRRect and borderRadius: BorderRadius.circular(8) in Container's decoration are used to make the rounded corners. The GestureDetector is used to make the button functionality.

Container(
  color: Colors.purpleAccent,
  child: Center(
    child: GestureDetector(
      onTap: () {
        print('tapped');
      },
      child: ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: ShaderMask(
          shaderCallback: (rect) =>
          LinearGradient(colors: [Colors.black], stops: [0.0])
          .createShader(rect),
          blendMode: BlendMode.srcOut,
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 20.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
            ),
            child: Text(
              'Press me',
              style: TextStyle(
                fontSize: 36,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
        ),
      ),
    ),
  ),
)

Result:

res

Mobina
  • 6,369
  • 2
  • 25
  • 41
  • Since only control going is on is "tap" (no dragging and alike) then I'd recommend going with InkWell instead of GestureDetector, for that simplistic but useful animation (gives feedback to the user). Real caveat is that adding vertical padding won't work with this approach, it will be present in the layout but it won't be painted black. Not trashing on your answer @Mobina heh, just pointing out some shortcomings that the OP / other readers might run into later, it is a fine answer given how immature flutter can be some times :). – Uroš Aug 25 '20 at 21:40
  • Using `InkWell` will cause a problem with the rounded corners. The vertical padding is an issue for sure. There is an ugly workaround which is not quite good: adding new line before and after the actual text and reducing the line height. Hope they add a proper widget for this purpose someday. @Uroš – Mobina Aug 25 '20 at 21:53
  • 1
    [InkWell](https://api.flutter.dev/flutter/material/InkWell/InkWell.html) can have a border radius of its own. So simply matching the radius `InkWell(onTap: () {print('tapped');}, borderRadius: BorderRadius.circular(8), ...` will get the desired effect (no glow/shade on the corners), as you can see on [this gif](https://drive.google.com/file/d/1jZQtGgv1FaT-pZhXpa-NMNxQKf9YfXYG/view). Heh yeah, hopefully hopefully one day we won't have to resort to these silly workarounds. – Uroš Aug 25 '20 at 22:16