Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate global key in the first screen #112

Open
iyar-avital opened this issue Dec 11, 2023 · 9 comments
Open

Duplicate global key in the first screen #112

iyar-avital opened this issue Dec 11, 2023 · 9 comments
Assignees
Labels
bug Something isn't working in triage

Comments

@iyar-avital
Copy link

Bug report

Duplicate global key on the content on the first page from two pages when moving to the second page.
image

Steps to reproduce

Steps to reproduce the behavior:

  1. Open a modal with two pages
  2. Move from the first page to the second
  3. The first page body is built twice and there is a duplicate global key exception

Expected behavior

The first page does not need to be rebuilt when moving to the second page

@iyar-avital iyar-avital added bug Something isn't working in triage labels Dec 11, 2023
@ulusoyca
Copy link
Collaborator

ulusoyca commented Dec 13, 2023

This is a difficult problem to solve due to how the slide motion during the pagination is implemented. This happens when your main content has a widget with GlobalKey. During the pagination the main content widgets are duplicated in the Offstage widget to be able to calculate the size.

This is not something we can quickly fix, but I will keep an eye on this. What is your use case? If you need a form key or something similar that will be used to refer the entire widget tree, injecting the key with the KeyedSubtree through the decorator field would help?

@iyar-avital
Copy link
Author

This is a problem for me.

I used the key inside a Form widget, when clicking on a button the validate() function invoke on this key.
The validate() function belongs to FormState class, so the key must be inside the form and the solution you gave me does not help.
the

In addition, I can't use Form.of instead of the key because the Form in the content of the modal and the button is located as StickyActionBar (The form does not contain the button.)

Do you have any idea for me?

@ulusoyca ulusoyca self-assigned this Jan 14, 2024
@tp
Copy link

tp commented Jan 17, 2024

I ran into the same issue when re-using some (proprietary) form component widgets that had GlobalKeys to scroll them into view.

@ulusoyca
Copy link
Collaborator

Thanks @tp We are aware of this. Currently, this issue is on me and I am trying to find time to address this issue. On top of my priority list. If you want to debug and create PR, I can give you background information on the root cause.

@tp
Copy link

tp commented Jan 17, 2024

I came up with this workaround for the app I am working on, where gladly we control all child widgets of the modal:

  @override
  Widget build(BuildContext context) {
    final isOffstage =
        context.findAncestorWidgetOfExactType<Offstage>()?.offstage == true;

    return Widget(
      // Do not set the key when rendering offstage (e.g. WoltModalSheet) to avoid duplicate `GlobalKey`s
      // (This will not impact any behavior as these are only needed for scrolling on-screen widgets anyway)
      key: isOffstage ? null : fieldItem.widgetKey,

@ulusoyca
Copy link
Collaborator

Very smart workaround! I will give a shot to a more proper solution. It is nice to know that a workaround is possible.

@kamami
Copy link

kamami commented Mar 1, 2024

I have the same issue, will remove the Form from the widget for now.

@stanislavlysenko0912
Copy link

stanislavlysenko0912 commented Apr 15, 2024

Any new solutions?
When i use

final isOffstage = context.findAncestorWidgetOfExactType<Offstage>()?.offstage == true;

On first page i got wrong true and i cant validate forms (for example).
But when change to any pages and going back, got right false.

UPD.
I found solution, looks bad but works.
Will be waiting maybe anyone suggest more elegant solution.

class _SignInWoltpageState extends State<SignInWoltpage> {
  bool isOffstageFromDelayedCheck = true;

  @override
  void initState() {
    super.initState();
    checkVisibilityInitially();
  }

  void checkVisibilityInitially() {
    Future.delayed(const Duration(milliseconds: 50), () {
      if (!mounted) return;

      setState(() {
        isOffstageFromDelayedCheck = context.findAncestorWidgetOfExactType<Offstage>()?.offstage ?? false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    final isOffstageFromBuildCheck = context.findAncestorWidgetOfExactType<Offstage>()?.offstage ?? true;
    final isOffstage = isOffstageFromDelayedCheck && isOffstageFromBuildCheck;

@PlaxXOnline
Copy link

Is there meanwhile another Solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working in triage
Projects
Status: 👀 In Progress
Development

No branches or pull requests

6 participants