Skip to content

Conversation

garbidge
Copy link

@garbidge garbidge commented May 23, 2024

Fixes issue #175

Description:

It seems like this can at times be called before it has been through layout (in particular when restoring state). Changed to first check hasSize before using size.

Reproduction steps:

Using minimal sample code included below:

  • In Android emulator, go to developer options and enable "Don’t keep activities"
  • Run app
  • Click on button to restorablePush second route
  • Use device buttons to put app in background
  • Use device buttons to return to the app
  • It will restore and encounter this error

If relevant, this was reproduced on Android 12, Flutter 3.22.0

Sample code:

import 'package:flutter/material.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  Widget getView(BuildContext subContext, RouteSettings routeSettings) {
    switch (routeSettings.name) {
      case WidgetB.routeName:
        return const WidgetB();
      default:
        return const WidgetA();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      restorationScopeId: "test",
      onGenerateRoute: (RouteSettings routeSettings) {
        var uri = Uri.parse(routeSettings.name ?? '');
        return MaterialPageRoute<void>(
          settings: routeSettings,
          builder: (BuildContext subContext) {
            return getView(subContext, RouteSettings(
                name: uri.path,
                arguments: routeSettings.arguments ?? uri.queryParameters));
          },
        );
      },
    );
  }
}

class WidgetA extends StatelessWidget {
  static const routeName = 'widget_a';

  const WidgetA({super.key,});

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      LinearPercentIndicator(),
      ElevatedButton(
        onPressed: () => Navigator.of(context).restorablePushNamed(WidgetB.routeName),
        child: const Text("Click me")
      )
    ],);
  }
}

class WidgetB extends StatelessWidget {
  static const routeName = 'widget_b';

  const WidgetB({super.key,});

  @override
  Widget build(BuildContext context) {
    return const Text("Now use device buttons to put app in background and then restore");
  }
}

@garbidge garbidge changed the title check hasSize before reading size [LinearPercentIndicator] Cannot get size from a render object that has not been through layout May 23, 2024
Copy link
Owner

@diegoveloper diegoveloper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!! , could you create a method extension for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants