How to avoid the conflict between the blur effect of Backdrop and the splash effect of TabBar in Flutter?

Viewed 200
class Sample extends StatelessWidget {
  List<Tab> get tabs => ["Intro", "Flow", "Market"]
      .map((e) => Tab(
            text: e,
          ))
      .toList(growable: false);

  @override
  Widget build(BuildContext context) {
    return Layout(
      title: "Title",
      body: CustomScrollView(
        slivers: [
          _buildHeader(),
          _buildStickyBar(),
        ],
      ),
    );
  }

  Widget _buildHeader() {
    return SliverToBoxAdapter(
      child: Stack(
        children: [
          Positioned(child: Image.assets("some.jpg"), top: 40, bottom: -20, right: -20),
          BackdropFilter(
            filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0),
            child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.white.withOpacity(0.06),
              ),
              child: Text("effect")),
          ),
        ],
      ),
    );
  }

  Widget _buildStickyBar() {
    return SliverPersistentHeader(
      pinned: true,
      floating: true,
      delegate: SliverPersistentHeaderEx(//some simple impl
        minHeight: 32,
        maxHeight: 32,
        child: TabBar(
          controller: tabController, //it's not the point
          tabs: tabs),
      ),
    );
  }
}

The theme used is a black theme, and the splash is white.

So, the blur effect and splash effect will conflict. In detail, the splash effect of TabBar will spread to the upper widget(stack, in this case). If you remove withOpacity, the blur effect will be lost, but the diffusion problem will be solved.

I want to keep those effects. How can I limit the splash effect of the TaBbar to only appear in the TabBar?

effect

1 Answers

As documentation says:

The filter will be applied to all the area within its parent or ancestor widget's clip. If there's no clip, the filter will be applied to the full screen.

Try to wrap your BackdropFilter with ClipRect

ClipRect(
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0),
          child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: Colors.white.withOpacity(0.06),
              ),
              child: Text("effect")),
        ),
      ),
Related