Kinda Code
Home/Flutter/Using BlockSemantics in Flutter: Tutorial & Example

Using BlockSemantics in Flutter: Tutorial & Example

Last updated: October 05, 2022

This article is about the BlockSemantics widget in Flutter.

Overview

Semantics are used by accessibility tools, bots, and other semantic analysis software to determine the meaning of the application. To be able to see the semantic stuff on iOS simulators or Android emulators, you can set the showSemanticsDebugger property of MaterialApp to true:

MaterialApp(
      showSemanticsDebugger: true,
      /* ... */
)

The BlockSemantics widget, as its name suggests, is used to exclude the semantics of all widgets painted before it in the same semantic container. This is helpful in some scenarios. For example, when a dialog or a drawer is showing, other widgets behind it should not have semantics.

Let’s have a glance at its constructor, as follows:

BlockSemantics({
  Key? key, 
  bool blocking = true, 
  Widget? child
})

Besides the typical key property, the widget doesn’t need too many arguments.

  • blocking: Blocking semantics or not.
  • child: the child widget.

For more clarity, let’s see the example below.

The Example

App Preview

The app we are going to make contains a floating button (that will be used to turn on or off the blocking), a group of dummy widgets including a button, a text field, and a text widget (whose semantics will be blocked later), and a BlockSemantics widget that wraps an amber box.

When showSemanticsDebugger is set to false, you will see this:

Once the semantics debugger is enabled, you will see this:

Let’s see the animated GIF demo for more clarity:

The Code

The complete source code in main.dart with detailed explanations:

// main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // hide the debug banner
      debugShowCheckedModeBanner: false,
      // show semantics debugger or not
      showSemanticsDebugger: true,
      title: 'KindaCode.com',
      theme: ThemeData(
        // use Material 3
        useMaterial3: true,
        primarySwatch: Colors.green,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // block semantics or not
  // this variable will change when you press the floating button
  bool _blocking = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('KindaCode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(15),
        child: Column(
          children: [
            // These widget are painted before BlockSemantics
            // Therefore, they will blocked semantics if the "blocking" argument of the BlockSemantics widget is set to "true"
            ElevatedButton(onPressed: () {}, child: const Text('Button 1')),
            const SizedBox(
              height: 15,
            ),
            const TextField(
              decoration: InputDecoration(border: OutlineInputBorder()),
            ),
            const SizedBox(
              height: 15,
            ),
            const Text('Just a text widget'),
            const SizedBox(
              height: 15,
            ),

            // The BlockSemantics stuff
            BlockSemantics(
              blocking: _blocking,
              child: Card(
                elevation: 6,
                child: Container(
                  width: 300,
                  height: 200,
                  color: Colors.amber,
                  child: const Center(
                    child: Text(
                      'Hello',
                      style: TextStyle(fontSize: 50),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      // change the blocking state
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _blocking = !_blocking;
          });
        },
        child: const Icon(Icons.block),
      ),
    );
  }
}

Conclusion

You’ve learned the fundamentals of the BlockSemantics widget and examined an end-to-end example of implementing it in action. This knowledge might be very helpful when developing Flutter web applications. If you’d like to explore more new and awesome features of Flutter, take a look at the following articles:

You can also check out our Flutter category page or Dart category page for the latest tutorials and examples.