4

Simple question for which it was impossible to me to find an answer.

I am from a web developer background where you can identify an UI component in html by an id which should be unique. I am looking to do the same in Flutter.

How can we uniquely identify widgets in flutter ?


Real world use case:

I want to track the displayed components and those who are interacted with to output statistics about them and refer them by their id.


My researches:

I have saw this question: the title describes exactly my problem but unfortunately the description and responses isn't at all relevant for my use case

I also couldn't find any reference to such a feature in the flutter doc

TOPKAT
  • 6,667
  • 2
  • 44
  • 72
  • 1
    Isn't that the purpose of widget keys? Or did I get you wrong? Check this out https://docs.flutter.dev/cookbook/testing/widget/finders#2-find-a-widget-with-a-specific-key – Khalil Dec 27 '21 at 09:26

3 Answers3

3

You can simply use a GlobalKey(). As its name suggests a unique global key is a key that can uniquely identify a widget in flutter. You just have to instantiate one, and pass it to the « key: » property of a widget. And you’re then able to access your widget’s data through that key, kind of like in html.

// A widget containing the observed widget and the widget showing stats about it.
class ParentWidget extends StatelessWidget {
  // We initiate the key here.
  // We want to create the key in a widget that will not be rebuilt, so it does not get reinitialized.
  final observedWidgetKey = GlobalKey();
  ParentWidget();

  @override
  Widget build(BuildContext context) {
    return Column(
      // We pass the key to both widgets.
      children: [ObservedWidget(key: observedWidgetKey), WidgetStats(observedWidgetKey: observedWidgetKey,)],
    );
  }
}

// The widget which we want to observe.
class ObservedWidget extends StatelessWidget {
  // Here we pass the key to the super constructor, meaning we assign it to the "key" property of the widget, a property that is present in all widgets in flutter.
  ObservedWidget({required Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text("Hello, I am a widget !");
  }
}

class WidgetStats extends StatelessWidget {
  final GlobalKey observedWidgetKey;
  WidgetStats({required this.observedWidgetKey});

  @override
  Widget build(BuildContext context) {
    // You can access all sorts of information inside the GlobalKey, this is just an example of what you could do.
    return Text(
        "Some data about the observed widget: ${observedWidgetKey.currentWidget?.toString()}");
  }
}

So, in this example, we have 3 widgets. One parent ParentWidget() will initialize the key, display some widget ObservedWidget() that should be observed, and a widget that shows stats about it StatsWidget(). The parent passes down the key to both widgets. The ObservedWidget() assigns the key to its key property while the StatsWidget() displays stats about the observed widget, that it found in the GlobalKey(). There are a lot of information about a widget that you can access in the GlobalKey(), depending on your usecase.

This is a simple example. What you have to remember is that the key should be initialized in a widget that does not rebuild, so at the top of you widgets tree. You could also use some state management solutions to initialise and keep your keys somewhere safe, to decouple it from your UI.

jeremynac
  • 1,204
  • 3
  • 11
2

Well as you took a reference from HTML in html we pass a id to elements manually or dynamically as well using some logic. In Flutter you can assign a Unique id to every widget but you also have to declare it first to get the values inside the key.

In Flutter you have two types of keys Local and Global.

Just define a key and pass that to any widget once the widget renders over the screen you can get values of the widget using that key.

Example Global Key

final formKey = GlobalKey<FormState>();

void addTodo() {
  // 3
  if (formKey.currentState!.validate()) {
    // 4
    formKey.currentState!.save();
    // 5
    return widget.onSubmitTap(todo);
  }
}

Form(
    // 2
    key: formKey,
    child: Padding(
      padding: const EdgeInsets.all(15),
      child: ...
    ),
  )

For more details refer to this - https://medium.com/flutter/keys-what-are-they-good-for-13cb51742e7d

Diwyansh
  • 2,961
  • 1
  • 7
  • 11
0

in your case ValueKey is more suitable I think. Here you can give your desired key, and you can control this keys

BosS
  • 447
  • 2
  • 9