반응형

https://aurimas-deimantas.medium.com/double-sliver-appbar-in-flutter-95d94627db07

 

Double Sliver AppBar in Flutter

After releasing my brand new and fully revamped RentMi v3, I got many enquiries from fellow developers on how did I do this fancy double…

aurimas-deimantas.medium.com

 

 

완전히 개선된 완전히 새로워진 RentMi v3을 출시한 후 동료 개발자들로부터 이 멋진 이중 AppBar를 어떻게 만들었는지 많은 문의를 받았습니다. , 스크롤하는 동안 축소/확장됩니다.

 

 

어렵지 않아요! 그러나 약간의 생각과 땀을 흘려야 하기 때문에 즉시 사용 가능한 것은 아닙니다. 하지만 크리스마스🎄가 코앞으로 다가왔으니 여기로 가져가세요!

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: DoubleAppBarDemo(),
    );
  }
}

class DoubleAppBarDemo extends StatelessWidget {
  final ScrollController _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
              snap: true,
              forceElevated: true,
              floating: true,
              title: Text("Double AppBar Demo"),
              actions: <Widget>[
                IconButton(icon: Icon(Icons.apps), onPressed: () {}),
              ],
              expandedHeight: 2 * kToolbarHeight,
              flexibleSpace: Padding(
                padding: const EdgeInsets.only(top: kToolbarHeight),
                child: Padding(
                  padding: const EdgeInsets.all(4.0),
                  child: Row(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(left: 8.0, right: 16),
                        child: RaisedButton(child: Text("Button One"), onPressed: () {}),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(left: 8.0, right: 16),
                        child: RaisedButton(child: Text("Button Two"), onPressed: () {}),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            SliverList(
                delegate: SliverChildListDelegate([
              ListView.builder(
                  controller: _scrollController,
                  shrinkWrap: true,
                  itemCount: 100,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text("$index"),
                    );
                  })
            ]))
          ],
        ),
      ),
    );
  }
}

복사 붙여넣기 — 즉시 사용할 수 있습니다.

 

 

이제 더 깊이 파고들고 싶은 분들을 위해 시작하겠습니다!

 

우선 전체 수축/확장 메커니즘을 위해서는 Sliver 위젯을 다루어야 합니다. 보다 사용자 정의된 스크롤 느낌을 제공합니다. 그러나 제가 직접 느낀 점은 애니메이션을 더 멋지게 만들고 싶고 사용자 정의 논리적 동작을 처리하는 데 더 많은 어려움이 있을 수 있다는 것입니다.
현재 구조는 매우 쉽습니다. Scaffold, SafeArea가 있습니다(잠시 후에 설명하겠습니다). , CustomScrollView (Slivers 처리에 도움이 됨), SliverAppBar (교환 일반 AppBar) 및 SliverList (ListView 대체)

 

CustomScrollView SafeArea 위젯으로 래핑해야 합니다. 올바른 패딩을 제공할 수 있는 능력 때문일 뿐만 아니라(새로운(?) 휴대폰 모델에서 노치나 더 많은 여유 하단 영역(iPhone X)이 있는 경우에 대비해 앱에 충분한 공간을 확보할 수 있도록 보장합니다.) 이러한 래핑이 없으면 앱이 그렇지 않을 수도 있습니다. 좋아 보여요.

 

모든 설정이 완료되면 완전히 확장된 후 SliverAppBar의 최대 높이를 제공해야 합니다. 간단히 말해서

expandedHeight: 2 * kToolbarHeight

그러면 일반 도구 모음 높이가 두 배로 늘어납니다.

그런 다음 flexibleSpace에 위젯을 제공해야 합니다. 원하는 위젯이 될 수 있으므로 창의성과 UIUX 디자인이 필요합니다. 이 데모에서는 몇 개의 버튼이 있는  을 선택하여 배치했습니다.

Padding(
  padding: const EdgeInsets.only(top: kToolbarHeight),
  child: Padding(
    padding: const EdgeInsets.all(4.0),
    child: Row(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(left: 8.0, right: 16),
          child: RaisedButton(child: Text("Button One"), onPressed: () {}),
        ),
        Padding(
          padding: const EdgeInsets.only(left: 8.0, right: 16),
          child: RaisedButton(child: Text("Button Two"), onPressed: () {}),
        ),
      ],
    ),
  ),
),

알 수 있는 점은 이 위젯에 약간의 패딩이 있다는 것입니다. 위에서만. 이는 기본적으로 flexibleSpace Widget이 전체 SliverAppBar

SliverAppBar 작업이 완료되면 마지막으로 남은 일은 스크롤할 수 있는 항목 목록을 표시하는 것입니다. ListView를 제공하여 SliverList 만 구성하면 그게 전부입니다!

SliverList(
  delegate: SliverChildListDelegate([
    ListView.builder(
        controller: _scrollController,
        shrinkWrap: true,
        itemCount: 100,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text("$index"),
          );
        })
  ]),
)

..아뇨, 그렇지는 않아요. 마지막으로 ScrollController를 초기화하고 이를 ListView에 할당해야 한다는 것입니다.

final ScrollController _scrollController = ScrollController();

거기에 없으면 목록이 스크롤되지 않습니다. 왜 물어보나요?

 

저도 같은 질문을 갖고 있습니다😅 목록 중첩(CustomListView 내부의 ListView + Sliver 매직) 때문인 것 같습니다.

이제 정말 결승선이에요! 우리는 간단하면서도 매우 강력한 스크롤링 경험을 가지고 있습니다.

 

 

반응형

+ Recent posts