web-dev-qa-db-fra.com

comment implémenter un sliverAppBar avec un tabBar

le document flutter montre un démo pour SliverAppBar + TabBar + TabBarView with ListView utiliser NestedScrollView, et c'est un peu complexe, donc je me demande s'il existe un moyen simple et clair de le mettre en œuvre. J'ai essayé ceci:

CustomScrollView
  slivers:
    SliverAPPBar
      bottom: TabBar
    TabBarView
      children: MyWidget(list or plain widget)

a eu une erreur:

flutter: l'assertion suivante a été émise en construisant Scrollable (axisDirection: right, physics:
flutter: un RenderViewport attend un enfant de type RenderSliver mais reçoit un enfant de type _RenderExcludableScrollSemantics.
Flutter: les objets RenderObjects attendent des types d’enfants spécifiques car ils se coordonnent lors de la présentation et de Paint. Par exemple, un RenderSliver ne peut pas être l'enfant d'un RenderBox car celui-ci ne comprend pas le protocole de présentation RenderBox.

et

flutter: Une autre exception a été lancée: 'package: flutter/src/widgets/framework.Dart': Échec de l'assertion: ligne 3497, position 14: 'propriétaire._debugCurrentBuildTarget == this': n'est pas vrai.

ICI IS MON CODE:

import 'package:flutter/material.Dart';

main(List<String> args) {
  runApp(MyScrollTabListApp());
}

class MyScrollTabListApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: "aa", home: MyScrollTabListHomePage());
  }
}

class MyScrollTabListHomePage extends StatefulWidget {
  @override
  MyScrollTabListHomePageState createState() {
    return new MyScrollTabListHomePageState();
  }
}

class MyScrollTabListHomePageState extends State<MyScrollTabListHomePage>
    with SingleTickerProviderStateMixin {
  final int _listItemCount = 300;
  final int _tabCount = 8;
  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: _tabCount, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            expandedHeight: 240.0,
            title: Text("Title"),
            pinned: true,
            bottom: TabBar(
              controller: _tabController,
              isScrollable: true,
              tabs: List<Tab>.generate(_tabCount, (int i) {
                return Tab(text: "TAB$i");
              }),
            ),
          ),
          TabBarView(
            controller: _tabController,
            children: List<Widget>.generate(_tabCount, (int i) {
              return Text('line $i');
            }),
          ),
        ],
      ),
    );
  }
}

et pour la démo officielle, il utilise une structure comme celle-ci

DefaultTabController
    NestedScrollView
      headerSliverBuilder
        SliverOverlapAbsorber
          handle
          SliverAppBar
        TabBarView
          CustomScrollView
            SliverOverlapInjector
              handle
              SliverPadding
3
walker

Voici un exemple pour TabView avec SilverAppBar 

class SilverAppBarWithTabBarScreen extends StatefulWidget {
  @override
  _SilverAppBarWithTabBarState createState() => _SilverAppBarWithTabBarState();
}

class _SilverAppBarWithTabBarState extends State<SilverAppBarWithTabBarScreen>
    with SingleTickerProviderStateMixin {
  TabController controller;

  @override
  void initState() {
    super.initState();
    controller = new TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new CustomScrollView(
        slivers: <Widget>[
          new SliverAppBar(
            title: Text("Silver AppBar With ToolBar"),
            pinned: true,
            expandedHeight: 160.0,
            bottom: new TabBar(
              tabs: [
                new Tab(text: 'Tab 1'),
                new Tab(text: 'Tab 2'),
                new Tab(text: 'Tab 3'),
              ],
              controller: controller,
            ),
          ),
          new SliverList(
          new SliverFillRemaining(
        child: TabBarView(
          controller: controller,
          children: <Widget>[
               Text("Tab 1"),
               Text("Tab 2"),
               Text("Tab 3"),
             ],
            ),
          ),
        ],
      ),
    );
  }
}
1
Dhiraj Sharma

Super vidéo ici expliquant tout. Il s'avère que vous avez besoin du contrôleur scrollView: https://youtu.be/3Cm7WzH3gb8

0
mikeyman22