Flutter 如何在底部屏幕上实现可滚动选项卡

Flutter 如何在底部屏幕上实现可滚动选项卡,flutter,Flutter,Newsvoice在屏幕底部的底部栏的顶部有一个可滚动的标签。我如何实现这个UI? 谢谢。下面是一些示例代码,它使用列将可滚动的选项卡栏和底部导航栏放置在脚手架的底部导航栏插槽中。请注意,当您使用动画交叉淡入法选择第二个(“摩托车”)屏幕时,选项卡将消失 导入“包装:颤振/材料.省道”; void main(){ runApp(新的MyApp()); } 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回新材料PP( 标题:“导航示例”, 主页:新建MyHomePage

Newsvoice在屏幕底部的底部栏的顶部有一个可滚动的标签。我如何实现这个UI?
谢谢。

下面是一些示例代码,它使用
将可滚动的
选项卡栏
底部导航栏
放置在
脚手架
底部导航栏
插槽中。请注意,当您使用动画交叉淡入法选择第二个(“摩托车”)屏幕时,选项卡将消失

导入“包装:颤振/材料.省道”;
void main(){
runApp(新的MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“导航示例”,
主页:新建MyHomePage(),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key}):超级(Key:Key);
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
常量列表选项卡名称=常量[
‘foo’、‘bar’、‘baz’、‘quox’、‘quuz’、‘corge’、‘grault’、‘garply’、‘waldo’
];
类_MyHomePageState扩展状态{
int _屏幕=0;
@凌驾
小部件构建(构建上下文){
返回新的DefaultTabController(
长度:tabNames.length,
儿童:新脚手架(
appBar:新的appBar(
标题:新文本(“导航示例”),
),
正文:新选项卡视图(
子项:新建List.generate(tabNames.length,(int索引){
开关(_屏幕){
案例0:返回新中心(
子项:新文本('第一个屏幕,${tabNames[index]}'),
);
案例1:返回新中心(
子项:新文本(“第二个屏幕”),
);
}
}),
),
底部导航栏:新列(
mainAxisSize:mainAxisSize.min,
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
新动画交叉淡入(
第一个孩子:新材料(
颜色:主题
.of(上下文)
.原色,
孩子:新的TabBar(
isScrollable:是的,
制表符:新建列表。生成(tabNames.length,(索引){
返回新选项卡(文本:tabNames[index].toUpperCase());
}),
),
),
第二个子项:新容器(),
crossFadeState:_屏幕==0
?CrossFadeState.showFirst
:crossfadstate.showSecond,
持续时间:常量持续时间(毫秒:300),
),
新底部导航栏(
当前索引:_屏幕,
onTap:(int索引){
设置状态(){
_屏幕=索引;
});
},
项目:[
新海底导航气压计(
图标:新图标(图标。airplanemode_激活),
标题:新文本(“飞机”),
),
新海底导航气压计(
图标:新图标(图标。摩托车),
标题:新文本(“摩托车”),
),
],
),
],
),
),
);
}
}

我不知道bottomNavigationBar接受小部件类型!我期待着像AppBar这样的限制。谢谢你,科林。
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Navigation Example',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

const List<String> tabNames = const<String>[
  'foo', 'bar', 'baz', 'quox', 'quuz', 'corge', 'grault', 'garply', 'waldo'
];

class _MyHomePageState extends State<MyHomePage> {

  int _screen = 0;

  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: tabNames.length,
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Navigation example'),
        ),
        body: new TabBarView(
          children: new List<Widget>.generate(tabNames.length, (int index) {
            switch (_screen) {
              case 0: return new Center(
                child: new Text('First screen, ${tabNames[index]}'),
              );
              case 1: return new Center(
                child: new Text('Second screen'),
              );
            }
          }),
        ),
        bottomNavigationBar: new Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            new AnimatedCrossFade(
              firstChild: new Material(
                color: Theme
                  .of(context)
                  .primaryColor,
                child: new TabBar(
                  isScrollable: true,
                  tabs: new List.generate(tabNames.length, (index) {
                    return new Tab(text: tabNames[index].toUpperCase());
                  }),
                ),
              ),
              secondChild: new Container(),
              crossFadeState: _screen == 0
                              ? CrossFadeState.showFirst
                              : CrossFadeState.showSecond,
              duration: const Duration(milliseconds: 300),
            ),
            new BottomNavigationBar(
              currentIndex: _screen,
              onTap: (int index) {
                setState(() {
                  _screen = index;
                });
              },
              items: [
                new BottomNavigationBarItem(
                  icon: new Icon(Icons.airplanemode_active),
                  title: new Text('Airplane'),
                ),
                new BottomNavigationBarItem(
                  icon: new Icon(Icons.motorcycle),
                  title: new Text('Motorcycle'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}