본문 바로가기

개발하자

앱 모음이 없는 플러터 탭 모음

반응형

앱 모음이 없는 플러터 탭 모음

앱바 없이 탭 바 레이아웃 화면을 만들려고 합니다. 나는 이미 이 링크에서 해결책을 참조했지만, 나에게는 효과가 없다. 다음은 매개 변수에 TabBar를 배치할 때 화면의 모양입니다:

enter image description here

내 탭 바가 상태 표시줄 아래 왼쪽 상단 모서리로 이동했고 모두 한쪽 모서리에 압착되었다. 마치 그것이 전혀 없는 것 같다.

AppBar 클래스를 사용하지만 매개 변수만 전달하면 다음과 같이 됩니다:

enter image description here

탭바 위에 보기 흉한 공간이 있는데, 이것은 분명히 앱바 제목을 위한 것이다. 제 코드는 다음과 같습니다:

return new Scaffold(
      appBar: new TabBar(
        tabs: widget._tabs.map((_Page page){
          return Text(page.tabTitle);
        }).toList(),
        controller: _tabController,
        isScrollable: true,

      ),
      backgroundColor: Colors.white,
      body: new TabBarView(
          controller: _tabController,
          children: widget._tabs.map((_Page page){
            return new SafeArea(
                top:false,
                bottom: false,
                child: (page.page == Pages.cart?new CartHomeScreen():_lunchesLayout())
            );
          }).toList()
      ),
    );

위에 공간 없이 어떻게 탭바만 가질 수 있고 두 개의 탭 항목과 표시기가 측면 공간을 확장하고 채울 수 있습니까?




여기 있어요. 이것은 주변에 스캐폴드나 재료 앱이 없는 위젯이므로 트리를 직접 제공해야 합니다. 그렇지 않으면 복사 붙여넣기가 가능합니다

import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin {
  late final TabController _tabController;

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

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      TabBar(controller: _tabController, tabs: const [
        Tab(icon: Icon(Icons.cookie_outlined)),
        Tab(icon: Icon(Icons.no_food))
      ]),
      Expanded(
          child: TabBarView(controller: _tabController, children: [
        Container(color: Colors.greenAccent),
        Container(color: Colors.yellowAccent)
      ]))
    ]);
  }
}



도구 모음을 사용한 권장 방법높이 속성

도구 모음 설정AppBar의 높이 속성을 0으로 설정하면 툴바가 제거되고 탭바는 테마별로 설정된 대로 맨 아래에 남습니다.

Scafford(
    appBar: AppBar(
        toolbarHeight: 0,
        bottom: TabBar(...)
    )
)



당신의 첫 스크린샷은 실제로 그것이 잘 작동한다는 것을 보여준다 - 문제는 '괜찮다'가 당신이 기대하는 것과 완전히 다르다는 것이다. 탭 표시줄의 기본 텍스트 색상은 흰색이므로 레이블은 표시되지 않고 맨 아래 줄만 왼쪽 상단에 표시됩니다. 또한, 탭바는 이미 선호되는 크기의 위젯이지만 앱바와 같은 높이를 가지고 있지 않기 때문에 만약 당신이 그것을 원하는 것이라면, 그것은 그렇게 보이지 않을 것이다.

다음은 앱 모음처럼 보이게 하는 예입니다. AppBar에서 사용하는 상수와 동일합니다.

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'msc',
      home: new DefaultTabController(
        length: 2,
        child: new Scaffold(
          appBar: new PreferredSize(
            preferredSize: Size.fromHeight(kToolbarHeight),
            child: new Container(
              color: Colors.green,
              child: new SafeArea(
                child: Column(
                  children: <Widget>[
                    new Expanded(child: new Container()),
                    new TabBar(
                      tabs: [new Text("Lunches"), new Text("Cart")],
                    ),
                  ],
                ),
              ),
            ),
          ),
          body: new TabBarView(
            children: <Widget>[
              new Column(
                children: <Widget>[new Text("Lunches Page")],
              ),
              new Column(
                children: <Widget>[new Text("Cart Page")],
              )
            ],
          ),
        ),
      ),
    );
  }
}

결과는 다음과 같습니다:

Screenshot showing tabbed app bar

편집:

설명 및 에서 언급한 바와 같이 AppBar의 FlexibleSpace 속성을 사용하여 기본적으로 동일한 효과를 유지할 수도 있습니다:

return new DefaultTabController(
  length: 3,
  child: new Scaffold(
    appBar: new AppBar(
      flexibleSpace: new Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          new TabBar(
            tabs: [
              new Tab(icon: new Icon(Icons.directions_car)),
              new Tab(icon: new Icon(Icons.directions_transit)),
              new Tab(icon: new Icon(Icons.directions_bike)),
            ],
          ),
        ],
      ),
    ),
  ),
);



나는 rmtmckenzie에서 코드를 받지만 재료 앱 없이 위젯을 만들기 위해서만

return new DefaultTabController(
      length: 3,
      child: new Scaffold(
        appBar: new PreferredSize(
          preferredSize: Size.fromHeight(kToolbarHeight),
          child: new Container(
            height: 50.0,
            child: new TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car,color: Colors.grey,)),
                Tab(icon: Icon(Icons.directions_transit,color: Colors.grey)),
                Tab(icon: Icon(Icons.directions_bike,color: Colors.grey)),
              ],
            ),
          ),
        ),
        body: TabBarView(
          children: [
            Icon(Icons.directions_car),
            Icon(Icons.directions_transit),
            Icon(Icons.directions_bike),
          ],
        ),
      ),
    ); 



그것의 소유지 안에 넣어보세요.




앱바의 하단 소품이 아닌 유연한 공간 소품만 사용하면 된다. 모두 안전한 영역 위젯에 있으며 수직 패딩을 추가할 수 있습니다.

home: SafeArea(
        top: true,
        child: Padding(
          padding: const EdgeInsets.only(top: 10.0),
          child: DefaultTabController(
            length: 3,
            child: Scaffold(
              appBar: AppBar(
                flexibleSpace: TabBar(
                  tabs: [
                    Tab(icon: Icon(Icons.1)),
                    Tab(icon: Icon(Icons.2)),
                    Tab(icon: Icon(Icons.3)),
                  ],
                ),
              ),
              body: TabBarView(
                children: [
                  Icon(Icons.1),
                  Icon(Icons.2),
                  Icon(Icons.3),
                ],
              ),
            ),
          ),
        ),
      )



이것은 매우 간단합니다. 당신이 제공해야 하는 모든 것은 당신의 것입니다.

여기 간단한 예가 있습니다. 또는 를 사용할 수 있습니다. 완전히 사용자 지정이 가능하려면 를 사용합니다.

탭의 함수 반환 목록입니다.

  TabBar _getTabBar() {
    return TabBar(
      tabs: <Widget>[
        Tab(icon: Icon(Icons.home, color: Colors.redAccent)),
        Tab(icon: Icon(Icons.settings, color: Colors.redAccent)),
      ],
      controller: tabController,
    );
  }

위젯 목록을 입력 인수로 사용하여 탭 보기를 만듭니다.

  TabBarView _getTabBarView(tabs) {
    return TabBarView(
      children: tabs,
      controller: tabController,
    );
  }

상태 표시줄 아래로 내용을 이동하는 데 사용됩니다. 높이를 할당할 수 있도록 a로 포장되어 있습니다. 이것은 높이를 할당하는 한 가지 방법입니다. 다른 방법을 사용할 수도 있습니다.

여기 전체 코드가 있습니다. 에 랩핑되어 있으며, 완전히 사용자 지정할 수 있는 탭 표시줄과 보기가 있습니다. 라이프사이클 방법은 생성 및 폐기에 사용된다

import 'package:flutter/material.dart';

class TabControllerScreen extends StatefulWidget {

  @override
  _TabControllerScreenState createState() => _TabControllerScreenState();
}

class _TabControllerScreenState extends State<TabControllerScreen> with SingleTickerProviderStateMixin {
  TabController tabController;

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

  @override
  void dispose() {
    tabController.dispose();
    super.dispose();
  }

  TabBar _getTabBar() {
    return TabBar(
      tabs: <Widget>[
        Tab(icon: Icon(Icons.home, color: Colors.redAccent)),
        Tab(icon: Icon(Icons.settings, color: Colors.redAccent)),
      ],
      controller: tabController,
    );
  }

  TabBarView _getTabBarView(tabs) {
    return TabBarView(
      children: tabs,
      controller: tabController,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            _getTabBar(),
            Container(
              height: 100,
              child: _getTabBarView(
                <Widget>[
                  Icon(Icons.home),
                  Icon(Icons.settings),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}




아래와 같이 값이 있는 위젯에서 속성을 사용하십시오:

Scaffold(
  appBar: AppBar(
    toolbarHeight: kMinInteractiveDimension,
    bottom: TabBar(
      controller: _tabController,
      tabs: [], // your tab bars
    ),
  ),
  body: TabBarView(
    controller: _tabController,
    children: [], // your tab views
  ),
);



아래 코드를 따릅니다

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  TabController _tabController;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Container(
              height: MediaQuery.of(context).size.height / 2,
              child: Center(
                child: Text(
                  "Tabbar with out Appbar",
                  style: TextStyle(
                      color: Colors.white, fontWeight: FontWeight.bold),
                ),
              ),
              color: Colors.blue,
            ),
            TabBar(
              unselectedLabelColor: Colors.black,
              labelColor: Colors.red,
              tabs: [
                Tab(
                  text: '1st tab',
                ),
                Tab(
                  text: '2 nd tab',
                )
              ],
              controller: _tabController,
              indicatorSize: TabBarIndicatorSize.tab,
            ),
            Expanded(
              child: TabBarView(
                children: [
                  Container(child: Center(child: Text('people'))),
                  Text('Person')
                ],
                controller: _tabController,
              ),
            ),
          ],
        ),
      ),
    );
  }
  
  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }
}

결과를 보다

enter image description here




속성에서 직접 사용:

@override
Widget build(BuildContext context) {
  return DefaultTabController(
    length: 2,
    child: Scaffold(
      appBar: TabBar(
        tabs: [
          Tab(icon: Icon(Icons.call)),
          Tab(icon: Icon(Icons.message)),
        ],
      ),
      body: TabBarView(
        children: [
          Center(child: Text('Call')),
          Center(child: Text('Message')),
        ],
      ),
    ),
  );
}



자산을 사용할 필요가 없습니다:

Scaffold(
  body: Column(
    children: [
      TabBar( // <-- Your TabBar
        tabs: [
          Tab(icon: Icon(Icons.camera)),
          Tab(icon: Icon(Icons.settings)),
        ],
      ),
      Expanded(
        child: TabBarView( // <-- Your TabBarView
          children: [
            Container(color: Colors.blue),
            Container(color: Colors.red),
          ],
        ),
      ),
    ],
  ),
)



CopsOnRoad의 답변에서, 나는 다음과 같은 숨겨진 탭바를 만들었다:

Scaffold(
  body: Column(
    children: [
      TabBar( // <-- Hidden TabBar
        indicator: BoxDecoration(),
        tabs: [
          SizedBox.shrink(),
          SizedBox.shrink(),
        ],
      ),
      Expanded(
        child: TabBarView( // <-- Your TabBarView
          children: [
            Container(color: Colors.blue),
            Container(color: Colors.red),
          ],
        ),
      ),
    ],
  ),
)

반응형