Flutter: Adaptive list-detail layout in flutter with auto_route?

27 Views Asked by At

I'm currently working on implementing a list-detail design in Flutter using the AutoRoute package. My objective is to create an adaptive layout where on larger screens, it displays as a dual-pane layout, while on smaller screens, it should transition to separate screens. Additionally, I need to highlight the list item corresponding to the currently selected detail item.

Resources:

However, I've encountered 3 major challenges:

  1. Tracking Active Inner Route: The list page, serving as a wrapper for the detail page, needs to identify the active inner route to highlight the currently selected item in the list.
  2. Route Configuration: If I include the details page as a child of the list, it functions correctly on larger screens. However, I'm unable to navigate to a new screen for the details without altering the routes property of the router, since it would require the details page to exist as an entirely separate route, instead of a child of ListRoute.
  3. Consistent Route on Device Configuration Changes: I need to ensure that the route remains consistent despite changes in device configuration. For instance, transitioning from a large screen with two panes to a smaller screen should adjust the detail screen to occupy the entire screen. In my current implementation it just "disappears" and shows up the list instead.

My router:

@AutoRouterConfig()
class AppRouter extends _$RepRouter {
  AppRouter(this.ref);

  @override
  List<AutoRoute> get routes => [
        AutoRoute(
          initial: true,
          page: ListRoute.page,
          children: [
            AutoRoute(
              page: DetailRoute.page
            ),
          ],
        ),
      ];
}

ListPage code:

@RoutePage()
class ListPage extends HookWidget {
  const ListPage({super.key});

  @override
  Widget build(BuildContext context) {
    
    // This widget will render only primary widget on smaller screens and
    // both primary and secondary on bigger screens
    return AdaptiveDualPaneLayout(  
      maxPrimaryWidth: 372,
      primary: list(context, null),
      secondaryBuilder: (context) => AutoRouter(
        placeholder: (context) => const Center(
          child: Text("Select an item first"),
        ),
      ),
    );
  }

  Widget list(BuildContext context, int? selectedItemId) {
    final strings = Strings.of(context);
    return CustomScrollView(
      slivers: [
        CustomSliverAppBar(
          title: Text("List-detail Layout"),
        ),
        SliverList.builder(
          itemBuilder: (context, index) => CustomListTile(
            elevation: index == selectedItemId ? 4 : 0,
            title: Text('Item $index'),
            subtitle: Text('Subtitle $index'),
            onTap: selectedItemId == index ? null : 
                () => AutoRouter.of(context).navigate(DetailRoute(id: index));
          ),
        ),
      ],
    );
  }
}


TL;DR:

  • How can I track the active inner route in the list page to highlight the selected item?
  • How can I ensure that, when the screen size is big enough, the details appear as a secondary pane (as currently implemented) while still enabling navigation to a new page when the screen is small?
  • How can I ensure that the route remains consistent when the device configuration changes, such as resizing the window? For instance, if the user has a large screen with two panes and item 1 displayed in the details page, resizing below the two-pane threshold should transition the detail screen to occupy the entire screen.
0

There are 0 best solutions below