实现此主屏幕的最佳方式是什么?

what is the best way to implement this home screen?

我想为我的 flutter 应用程序创建一个主页。我使用了网络上的模板,但不幸的是我没有按照我在图片中绘制的方式得到它。也许有人可以帮助我

sketch / result

不幸的是,我确定我不能做得更好:-/,希望它与左边的完全一样(图标和颜色不是那么重要)

我用论坛里的这个link作为应用栏的模板,插入有点困难^^

我也从论坛的某个地方得到了 BottomNavigationBar 的代码,但我认为这无论如何都不适合我的目的。由于我不喜欢这种点击时的收缩效果,所以边缘的两个箭头按钮在按下时应该弹回而不是一直处于按下状态,因为它们应该代表前后功能...

这是我的完整main.dart

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.light,
      theme: ThemeData(
          primaryColor: Color(0xFF34445c),
          primaryColorBrightness: Brightness.light,
          brightness: Brightness.light,
          primaryColorDark: Colors.black,
          canvasColor: Color(0xFFCECECE),
          appBarTheme: AppBarTheme(brightness: Brightness.light)),
      darkTheme: ThemeData(
          primaryColor: Colors.black,
          primaryColorBrightness: Brightness.dark,
          primaryColorLight: Colors.black,
          brightness: Brightness.dark,
          primaryColorDark: Colors.black,
          indicatorColor: Colors.white,
          canvasColor: Colors.black,
          appBarTheme: AppBarTheme(brightness: Brightness.dark)),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final _selectedItemColor = Colors.white;
  final _unselectedItemColor = Colors.white30;
  final _selectedBgColor = Color(0xFF293749);
  final _unselectedBgColor = Color(0xFF34445c);
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
  TextStyle(fontSize: 15, fontWeight: FontWeight.normal);
  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: ZURÜCK',
      style: optionStyle,
    ),
    Text(
      'Index 1: FAVORITES',
      style: optionStyle,
    ),
    Text(
      'Index 2: KOMMENTARE / LÖSCHEN',
      style: optionStyle,
    ),
    Text(
      'Index 3: ABOUT-US',
      style: optionStyle,
    ),
    Text(
      'Index 4: WEITER',
      style: optionStyle,
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  Color _getBgColor(int index) =>
      _selectedIndex == index ? _selectedBgColor : _unselectedBgColor;

  Color _getItemColor(int index) =>
      _selectedIndex == index ? _selectedItemColor : _unselectedItemColor;

  Widget _buildIcon(IconData iconData, String text, int index) => Container(
    width: double.infinity,
    height: kBottomNavigationBarHeight,
    child: Material(
      color: _getBgColor(index),
      child: InkWell(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(iconData),
            Text(text,
                style: TextStyle(fontSize: 9, color: _getItemColor(index))),
          ],
        ),
        onTap: () => _onItemTapped(index),
      ),
    ),
  );

  _appBar(height) => PreferredSize(
    preferredSize:  Size(MediaQuery.of(context).size.width, height+80 ),
    child: Stack(
      children: <Widget>[
        Container(
          child: Center(
            child: Text("TEXT", style: TextStyle(fontSize: 15.0,
                fontWeight: FontWeight.w600,
                color: Colors.white),
            ),

          ),
          color:Theme.of(context).primaryColor,
          height: height+75,
          width: MediaQuery.of(context).size.width,
        ),
        Container(
        ),
        Positioned(    // To take AppBar Size only
          top: 100.0,
          left: 20.0,
          right: 20.0,
          child: AppBar(
            backgroundColor: Color(0xFF293749),
            leading: Icon(Icons.menu, color: Colors.white),
            primary: false,
            title: Container(
              margin: EdgeInsets.only(top: 4.0, bottom: 4.0, right: 0.0, left: 0.0),
              color: Colors.white,
              child: Container(
                margin: EdgeInsets.only(top: 0.0, bottom: 0.0, right: 5.0, left: 5.0),
                child: TextField(
                    decoration: InputDecoration(
                        hintText: "Suchen",
                        border: InputBorder.none,
                        hintStyle: TextStyle(color: Colors.grey))),
              ),
            ),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.search, color: Colors.white), onPressed: () {},),
            ],
          ),
        )
      ],
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(AppBar().preferredSize.height),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        selectedFontSize: 0,
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.arrow_back_ios_rounded, 'ZURÜCK', 0),
            title: SizedBox.shrink(),
          ),
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.favorite, 'FAVORITEN', 1),
            title: SizedBox.shrink(),
          ),
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.comment, 'KOMMENTARE', 2),
            title: SizedBox.shrink(),
          ),
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.info_outline_rounded, 'ÜBER UNS', 3),
            title: SizedBox.shrink(),
          ),
          BottomNavigationBarItem(
            icon: _buildIcon(Icons.arrow_forward_ios_rounded, 'WEITER', 4),
            title: SizedBox.shrink(),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: _selectedItemColor,
        unselectedItemColor: _unselectedItemColor,
      ),
    );
  }
}

我已经修改了您的代码并添加了一些注释以支持您构建 UI。

对于 AppBar,您正朝着正确的方向使用 PreferredSizeStack,只是一些小的调整。

对于 BottomNavigationBar,由于提供的 BottomNavigationBarItem 已经具有 icontitle 属性,我们可以使用它并修改其父项的颜色。 2 个箭头按钮可以放在 Row.

完整示例如下:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.light,
      theme: ThemeData(
          primaryColor: Color(0xFF34445c),
          primaryColorBrightness: Brightness.light,
          brightness: Brightness.light,
          primaryColorDark: Colors.black,
          canvasColor: Color(0xFFCECECE),
          appBarTheme: AppBarTheme(brightness: Brightness.light)),
      darkTheme: ThemeData(
          primaryColor: Colors.black,
          primaryColorBrightness: Brightness.dark,
          primaryColorLight: Colors.black,
          brightness: Brightness.dark,
          primaryColorDark: Colors.black,
          indicatorColor: Colors.white,
          canvasColor: Colors.black,
          appBarTheme: AppBarTheme(brightness: Brightness.dark)),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final _selectedItemColor = Colors.white;
  final _unselectedItemColor = Colors.white30;
  final _selectedBgColor = Color(0xFF293749);
  final _unselectedBgColor = Color(0xFF34445c);
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 15, fontWeight: FontWeight.normal);

  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Index 0: ZURÜCK',
      style: optionStyle,
    ),
    Text(
      'Index 1: FAVORITES',
      style: optionStyle,
    ),
    Text(
      'Index 2: KOMMENTARE / LÖSCHEN',
      style: optionStyle,
    ),
    Text(
      'Index 3: ABOUT-US',
      style: optionStyle,
    ),
    Text(
      'Index 4: WEITER',
      style: optionStyle,
    ),
  ];

  _appBar() => PreferredSize(
        preferredSize: Size.fromHeight(300),
        child: Container(
          height: 300,
          child: Stack(
            children: <Widget>[
              Container(
                color: Color(0xFF34445D),
                height: 180,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      "APP TITLE",
                      style: TextStyle(
                          fontSize: 20.0,
                          fontWeight: FontWeight.w600,
                          color: Colors.white),
                    ),
                    SizedBox(height: 20),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: List<Widget>.generate(
                        4,
                        (index) => Padding(
                          padding: EdgeInsets.symmetric(horizontal: 8.0),
                          child: Icon(Icons.people, color: Colors.white), // Sample icons for demonstration
                        ),
                      ),
                    )
                  ],
                ),
              ),
              Positioned(
                top: 150.0,
                left: 20.0,
                right: 20.0,
                child: Container(
                  color: Color(0xFF293749),
                  child: Row(
                    children: [
                      IconButton(
                        icon: Icon(Icons.menu, size: 40, color: Colors.white),
                        padding: EdgeInsets.zero,
                        onPressed: () {},
                      ),
                      Expanded(
                        child: Container(
                          margin: EdgeInsets.symmetric(vertical: 3),
                          padding: EdgeInsets.only(left: 3),
                          color: Colors.white,
                          height: 30,
                          child: TextField(
                            style: TextStyle(color: Colors.black, fontSize: 12),
                            decoration: InputDecoration(
                                hintText: 'Search...',
                                border: InputBorder.none),
                          ),
                        ),
                      ),
                      IconButton(
                        icon: Icon(Icons.search, size: 30, color: Colors.white),
                        padding: EdgeInsets.zero,
                        onPressed: () {},
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBar(),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: Container(
        color: _selectedBgColor,
        child: Row(
          children: [
            IconButton(
              icon: Icon(Icons.arrow_back_ios, color: Colors.white),
              onPressed: () {
                setState(() {
                  _selectedIndex =
                      _selectedIndex <= 0 ? _selectedIndex : _selectedIndex - 1;
                });
              },
            ),
            Expanded(
              child: BottomNavigationBar(
                type: BottomNavigationBarType.fixed, // Add the type here to avoid auto resize
                backgroundColor: _selectedBgColor, // You can also set the unselectedBackgroundColor
                currentIndex: _selectedIndex,
                onTap: (index) => setState(() => _selectedIndex = index), // Update the selected index
                selectedItemColor: _selectedItemColor,
                unselectedItemColor: _unselectedItemColor,
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                      icon: Icon(Icons.favorite), title: Text('FAVORITEN')),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.comment), title: Text('KOMMENTARE')),
                  BottomNavigationBarItem(
                      icon: Icon(Icons.info_outline_rounded),
                      title: Text('ÜBER UNS')),
                ],
              ),
            ),
            IconButton(
              icon: Icon(Icons.arrow_forward_ios, color: Colors.white),
              onPressed: () {
                setState(() {
                  _selectedIndex =
                      _selectedIndex >= 2 ? _selectedIndex : _selectedIndex + 1;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}