Skip to content

Synchronizing Configs of Widgets with Keys #240

Description

@FlutterIssues

Issue by afandria
Thursday Oct 29, 2015 at 07:47 GMT
Originally opened as https://github.com/flutter/engine/issues/1867


The Flutter tutorial is quite helpful at clarifying the framework, but I think that the section on Keys can be clarified. My understanding of sync is that it is connected to the notion of config in StatefulComponents. I think it would be good to tie it back to the description (a few paragraphs earlier).

It also appears that key-based synchronization does not always occur. I looked at framework.dart's updateChildren method, and it says that this synchronization only happens for sibling widgets that share the same keys.

For example, this Widget Tree scenario should move the two children without changing their original configurations.

Stack
  MyChild with key1
  MyChild with key2

to

Stack
  MyChild with key2
  MyChild with key1

The above scenario should work well for most layouts (Flex/Row/Column/Block/Grid).

However, Stack is problematic when the children are in Positioned: here, the keyed Widgets are cousins, not siblings.

Stack
  Positioned
    MyChild with key1
  Positioned
    MyChild with key2

to

Stack
  Positioned
    MyChild with key2
  Positioned
    MyChild with key1

Since Stack children are usually Positioned, this second scenario should be quite common. However, the code (and my observations) show that the children would not sync with their original configurations (instead, they trade).

I think the fact that keys only affect sync of sibling widgets is very important to convey. However, I expected key-based matching to occur regardless of the actual layout of the Widget tree. Is sibling-only sync an intentional choice by the Flutter framework?

If it is, how can I synchronize my Stack's Positioned keyed children?
Note: I think I can work around the "cousins not syncing" issue in my app by reworking it. To make the keyed widgets be siblings again, I will pass the coordinates to them instead of to a Positioned. The widgets will use a SlideTransition to get into place. (IIRC, I don't think I can have my top-level child widget be a Positioned. Is there an alternative widget that won't animate?)

Please let me know if you have questions, or if I got something wrong. Thank you!

Activity

  1. FlutterIssues commented on Nov 9, 2015

    @FlutterIssues
    Author

    Comment by abarth
    Thursday Oct 29, 2015 at 16:53 GMT


    Is sibling-only sync an intentional choice by the Flutter framework?

    Yes. There are two kinds of keys, local keys and global keys. If you use local keys, their scope is just their own sibling list. If you use global keys, their scope is the entire tree. Local keys are more efficient but less powerful.

    If it is, how can I synchronize my Stack's Positioned keyed children?

    You have two choices: (1) you can add keys to the Positioned widgets:

    Stack
      Positioned with key1
        MyChild with key1
      Positioned with key2
        MyChild with key2
    

    (2) you can use global keys:

    Stack
      Positioned
        MyChild with global key1
      Positioned
        MyChild with global key2
    

    The global keys will let your widgets sync anywhere in the tree. The tradeoff is that (1) is more efficient than (2) but you can't always arrange for it to happen whereas.

  2. FlutterIssues commented on Nov 9, 2015

    @FlutterIssues
    Author

    Comment by afandria
    Friday Oct 30, 2015 at 07:37 GMT


    I missed the point on Global Keys, so it does look like sync covers the most important cases. I think these distinctions are worth adding to the tutorial.

    My app now keys the Positioned as well, as in solution (1). (I was unable to remove Positioned since MyChild expanded to fill the full Stack without it.)

    It turns out that my app was using global keys as in solution (2). It looks like it did sync the MyChild configurations correctly, though a combination of other bugs made that difficult to see.

    Aside: Unfortunately, (2) will not work for my app specifically because my app does global vs local Point computations for each SlideTransition animation. Since MyChild computes its local animation destination, if it's wrapping Positioned parent is swapped out, then it will not realize that it is animating to the wrong location.

  3. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Nov 20, 2015
  4. added this to the milestone on Dec 12, 2015
  5. sethladd commented on Nov 21, 2016

    @sethladd
    Contributor

    How do we take action on this? Is this for documentation, or also enhancements/changes to the framework?

  6. Hixie commented on Jan 29, 2017

    @Hixie
    Contributor

    The issues being discussed here are mostly obsolete now.

  7. github-actions commented on Aug 17, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  8. locked as resolved and limited conversation to collaborators on Aug 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    frameworkflutter/packages/flutter repository. See also f: labels.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions