0

pageview.builder インデックスのタイトルを持つ sliverAppBar で pageview.builder を作成しようとしています。あるページで sliverAppBar を折りたたむと、次のページにスワイプしても折りたたまれたままになることを願っています。

現在、最初のページでスライバーを折りたたむと、次のページにスクロールするとすぐに、拡張された高さに戻ります

ナビゲーション モデル

class NavigationModel {
  final String id;
  late final String title;
  List<String>? buttonNames;
  final String navImage;

  NavigationModel(
      {required this.id,
      required this.title,
      this.buttonNames,
      required this.navImage});
}

List<NavigationModel> navigation = [
  NavigationModel(
      id: 'A',
      title: 'A',
      buttonNames: [],
      navImage: 'assets/images/beach4.jpg'),
  NavigationModel(
      id: 'C',
      title: 'C',
      buttonNames: [],
      navImage: 'assets/images/beach4.jpg'),
  NavigationModel(
      id: 'P',
      title: 'P',
      buttonNames: [],
      navImage: 'assets/images/beach4.jpg'),
  NavigationModel(
      id: 'V',
      title: 'V',
      buttonNames: [],
      navImage: 'assets/images/beach4.jpg'),
  NavigationModel(
      id: 'S',
      title: 'S',
      buttonNames: [],
      navImage: 'assets/images/beach4.jpg'),
];

ナビゲーション バナー

@override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: navigation.length,
      itemBuilder: (BuildContext nav, index) {
        return Padding(
          padding: EdgeInsets.only(bottom: 16),
          child: Row(
            children: [
              Expanded(
                  child: Stack(
                children: [
                  Align(
                    alignment: Alignment.center,
                    child: GestureDetector(
                      onTap: () async {
                        _animationController.forward(from: 0.0);
                        stateNotifier.value = await Navigator.of(context).push(
                          FadePageRoute(
                              fullscreenDialog: true,
                              builder: (context) {
                                return PageView.builder(
                                    controller: PageController(
                                        initialPage: index, keepPage: true),
                                    itemBuilder: (context, position) {
                                      return NavigatedPage(
                                        selectedIndex:
                                            position % navigation.length,
                                      );
                                    });
                              }),
                        );
                      },
                      child: Hero(
                          tag: '${navigation[index].id}-img',
                          child: Image.asset(
                            'assets/images/beach4.jpg',
                            fit: BoxFit.cover,
                            height: 60,
                            width: MediaQuery.of(context).size.width * 0.95,
                          )),
                    ),
                  ),
                  Align(
                    alignment: Alignment.bottomLeft,
                    child: Container(
                        padding: EdgeInsets.only(top: 35, left: 14),
                        width: 180,
                        child: Hero(
                          tag: '${navigation[index].id}-title',
                          flightShuttleBuilder: (
                            BuildContext flightContext,
                            Animation<double> animation,
                            HeroFlightDirection flightDirection,
                            BuildContext fromHeroContext,
                            BuildContext toHeroContext,
                          ) {
                            return NavigationTitle(
                              title: navigation[index].title,
                              viewState:
                                  flightDirection == HeroFlightDirection.push
                                      ? ViewState.enlarge
                                      : ViewState.shrink,
                              isOverflow: true,
                              smallFontSize: 15.0,
                              largeFontSize: 32.0,
                            );
                          },
                          child: NavigationTitle(
                            title: navigation[index].title,
                            viewState: ViewState.shrunk,
                          ),
                        )),
                  ),
                ],
              ))
            ],
          ),
        );
      },
    );

ナビゲーションページ

@override
  Widget build(BuildContext context) {
    contentSpacing = MediaQuery.of(context).size.width;
    return WillPopScope(
        onWillPop: () {
          Navigator.of(context).pop(true);
          return Future.value(false);
        },
        child: Scaffold(
            body: NestedScrollView(
          headerSliverBuilder: (context, innerBoxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                snap: false,
                pinned: true,
                floating: false,
                flexibleSpace: FlexibleSpaceBar(
                  centerTitle: true,
                  title: Text(navigation[currentIndex].title),
                  background: Image.asset(
                    navigation[currentIndex].navImage,
                    fit: BoxFit.cover,
                  ),
                ),
                expandedHeight: 230,
                backgroundColor: Colors.greenAccent[400],
                leading: IconButton(
                  icon: Icon(Icons.menu),
                  tooltip: 'Menu',
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ), //IconButton
                actions: <Widget>[
                  IconButton(
                    icon: Icon(Icons.comment),
                    tooltip: 'Comment Icon',
                    onPressed: () {},
                  ), //IconButton
                  IconButton(
                    icon: Icon(Icons.settings),
                    tooltip: 'Setting Icon',
                    onPressed: () {},
                  ),
                ],
              ),
            ];
          },
          body: Column(
            children: [
              Container(
                height: 200,
                child: ListView.builder(
                  itemCount: navigation[currentIndex].buttonNames!.length,
                  itemBuilder: (
                    BuildContext ctx,
                    int index,
                  ) {
                    return Column(
                      children: [
                        ElevatedButton(
                          onPressed: () async {
                            await Navigator.pushNamed(
                                ctx,
                                navigation[currentIndex]
                                    .buttonNames![index]
                                    .toString());
                          },
                          child: Text(navigation[currentIndex]
                              .buttonNames![index]
                              .toString()),
                        ),
                      ],
                    );
                  },
                ),
              ),
            ],
          ),
        )));
  }
}

class NavContent extends StatelessWidget {
  final bool isHero;
  final double dx;
  final double initialDx;
  final NavigationModel destination;

  const NavContent({
    Key? key,
    required this.destination,
    this.isHero = false,
    this.dx = 0.0,
    this.initialDx = 0.0,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double maxOffset = MediaQuery.of(context).size.width;

    return ListView(
      children: <Widget>[
        ConstrainedBox(
          constraints: BoxConstraints(
            maxHeight: 380.0,
          ),
          child: Stack(
            clipBehavior: Clip.none,
            children: <Widget>[
              Align(
                alignment: Alignment.topCenter,
                child: isHero
                    ? Hero(
                        tag: 'PocketPK',
                        child: Header(
                          viewState: ViewState.shrunk,
                        ),
                      )
                    : Container(),
              ),
              Positioned(
                top: 50.0,
                left: dx * 1.5,
                child: Opacity(
                  opacity: isHero ? 1.0 - (dx.abs() / maxOffset) : 1.0,
                  child: Hero(
                    tag: isHero ? '${destination.id}-img' : 'img',
                    child: Image.asset(
                      destination.navImage,
                      fit: BoxFit.cover,
                      width: MediaQuery.of(context).size.width * 0.9,
                      height: 300.0,
                    ),
                  ),
                ),
              ),
             
              Positioned(
                top: 280.0,
                left: dx * 1.4 + 16.0,
                child: FractionalTranslation(
                  translation: Offset(0.0, 0.5),
                  child: Opacity(
                    opacity: isHero ? 1.0 - (dx.abs() / maxOffset) : 1.0,
                    child: Hero(
                      tag: isHero ? '${destination.id}-title' : 'title',
                      child: NavigationTitle(
                        title: destination.title,
                        viewState: ViewState.enlarged,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
       
      ],
    );

ゴール

https://twitter.com/i/status/1001705364587466752

https://github.com/Ramotion/navigation-toolbar-android/raw/master/Navigation-toolbar.gif

4

0 に答える 0